Haskell where 子句中的类型映射(-> 运算符)?
Haskell type-mapping (-> operator) in where clause?
我正在尝试理解 this article 中的代码。它解释了归纳图的使用,这看起来非常好,并且在某些时候它定义了对归纳图的深度优先搜索。它的代码如下:
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)
我不明白这两行:
go (n:ns) (match n -> (Just c, g)) =
n : go (Graph.neighbors' c ++ ns) g
它似乎正在定义函数 go
,它以列表作为第一个参数,由 (n:ns)
进行模式匹配。但是,第二个参数我不明白:(match n -> (Just c, g))
。这里的运算符 ->
是什么意思?通过查找运算符,它可以是以下三种情况之一:
- 函数类型映射运算符。
- Lambda 定义运算符。
- 案例结构中的分隔符。
由于没有case
语句,也没有lambda表达式的反斜杠转义变量,只能是函数类型映射运算符。在这种情况下,我不明白它是如何将值绑定到这些变量的,c
和 g
?它到底是什么意思,怎么会在争论中呢?
提前致谢!
在这种情况下,->
既不表示 function-type 也不表示 lambda-definition 也不表示 case-mapping。这是一个 view pattern.
go (n:ns) (match n -> (Just c, g)) =
n : go (Graph.neighbors' c ++ ns) g
相当于
go (n:ns) g'
| (Just c, g) <- match n g'
= n : go (Graph.neighbors' c ++ ns) g
其中 pattern guard (Just c, g) <- match n g'
又是
的缩写
go (n:ns) g' = case match n g' of
(Just c, g) -> n : go (Graph.neighbors' c ++ ns) g
(Nothing, g) -> ...
其中 Nothing
子句需要代表 go
定义的后面的子句。
这是一个view pattern。这个扩展允许我们在匹配之前以某种方式转换参数。
如果没有这个扩展,代码将不得不这样写:
go (n:ns) g' =
case match n g' of
(Just c, g) -> ...
...
这有点冗长。
我正在尝试理解 this article 中的代码。它解释了归纳图的使用,这看起来非常好,并且在某些时候它定义了对归纳图的深度优先搜索。它的代码如下:
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)
我不明白这两行:
go (n:ns) (match n -> (Just c, g)) =
n : go (Graph.neighbors' c ++ ns) g
它似乎正在定义函数 go
,它以列表作为第一个参数,由 (n:ns)
进行模式匹配。但是,第二个参数我不明白:(match n -> (Just c, g))
。这里的运算符 ->
是什么意思?通过查找运算符,它可以是以下三种情况之一:
- 函数类型映射运算符。
- Lambda 定义运算符。
- 案例结构中的分隔符。
由于没有case
语句,也没有lambda表达式的反斜杠转义变量,只能是函数类型映射运算符。在这种情况下,我不明白它是如何将值绑定到这些变量的,c
和 g
?它到底是什么意思,怎么会在争论中呢?
提前致谢!
->
既不表示 function-type 也不表示 lambda-definition 也不表示 case-mapping。这是一个 view pattern.
go (n:ns) (match n -> (Just c, g)) =
n : go (Graph.neighbors' c ++ ns) g
相当于
go (n:ns) g'
| (Just c, g) <- match n g'
= n : go (Graph.neighbors' c ++ ns) g
其中 pattern guard (Just c, g) <- match n g'
又是
go (n:ns) g' = case match n g' of
(Just c, g) -> n : go (Graph.neighbors' c ++ ns) g
(Nothing, g) -> ...
其中 Nothing
子句需要代表 go
定义的后面的子句。
这是一个view pattern。这个扩展允许我们在匹配之前以某种方式转换参数。
如果没有这个扩展,代码将不得不这样写:
go (n:ns) g' =
case match n g' of
(Just c, g) -> ...
...
这有点冗长。