Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • Function type-mapping operator.
  • Lambda definition operator.
  • Separator in case construction.

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!

like image 780
Goens Avatar asked Jan 25 '16 12:01

Goens


2 Answers

-> 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.

like image 104
leftaroundabout Avatar answered Oct 24 '22 12:10

leftaroundabout


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.

like image 35
Lambda Fairy Avatar answered Oct 24 '22 12:10

Lambda Fairy