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!
->
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With