Goens
Goens

Reputation: 415

Haskell type-mapping (-> operator) in where clause?

I am trying to understand the code in this article. It explains the use of inductive graphs, which seems very nice, and at some point it defines a depth-first search for inductive graphs. The code for it is the following:

dfs :: Graph.Node -> Gr a b -> [Node]
dfs start graph = go [start] graph
  where go [] _                            = []
        go _ g | Graph.isEmpty g           = []
        go (n:ns) (match n -> (Just c, g)) =
          n : go (Graph.neighbors' c ++ ns) g
        go (_:ns) 

I do not understand these two lines:

        go (n:ns) (match n -> (Just c, g)) =
          n : go (Graph.neighbors' c ++ ns) g

It seems it is defining the function go, which takes a list as a first argument, which is pattern-matched by (n:ns). The second argument, however, I do not understand: (match n -> (Just c, g)). What does the operator -> mean here? By looking the operator up, it can be one of three things:

Since there is no case statement, nor a backslash-escaped variable for a lambda expression, it can only be the case that it is the function type-mapping operator. In this case, I don't get how it is binding values to these variables, c and g? And what does it mean exactly, how can it be in an argument?

Thanks in advance!

Upvotes: 5

Views: 242

Answers (2)

Lambda Fairy
Lambda Fairy

Reputation: 14734

It is a view pattern. This extension lets us transform the argument somehow before matching on it.

Without this extension, the code would have to be written like this:

go (n:ns) g' =
  case match n g' of
    (Just c, g) -> ...
    ...

which is a bit more verbose.

Upvotes: 3

leftaroundabout
leftaroundabout

Reputation: 120751

-> means neither function-type nor lambda-definition nor case-mapping in this case. It is a view pattern.

go (n:ns) (match n -> (Just c, g)) =
      n : go (Graph.neighbors' c ++ ns) g

is equivalent to

go (n:ns) g'
  | (Just c, g) <- match n g'
        = n : go (Graph.neighbors' c ++ ns) g

where the pattern guard (Just c, g) <- match n g' is in turn short for

go (n:ns) g' = case match n g' of
   (Just c, g) -> n : go (Graph.neighbors' c ++ ns) g
   (Nothing, g) -> ...

where the Nothing clause needs to stand in for the later clause of the go definition.

Upvotes: 8

Related Questions