where子句中的Haskell类型映射( - >运算符)?

时间:2016-01-25 12:41:27

标签: haskell types 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表达式的反斜杠转义变量,因此只能是函数类型映射运算符。在这种情况下,我不知道它是如何绑定这些变量cg的?它到底是什么意思,怎么会出现在争论中呢?

提前致谢!

2 个答案:

答案 0 :(得分:8)

在这种情况下,

->既不表示函数类型,也不表示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定义的后一句。

答案 1 :(得分:3)

这是view pattern。这个扩展允许我们在匹配之前以某种方式转换参数。

如果没有此扩展名,代码必须按如下方式编写:

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

这有点冗长。

相关问题