【问题标题】:Haskell type-mapping (-> operator) in where clause?在 where 子句中的 Haskell 类型映射(-> 运算符)?
【发布时间】:2016-01-25 12:41:27
【问题描述】:

我正在尝试理解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?它到底是什么意思,怎么可能出现在争论中?

提前致谢!

【问题讨论】:

    标签: haskell types where-clause


    【解决方案1】:

    -> 在这种情况下既不是函数类型,也不是 lambda 定义,也不是大小写映射。这是一个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) &lt;- 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 定义的后面的子句。

    【讨论】:

      【解决方案2】:

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

      如果没有这个扩展,代码就必须这样写:

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

      这有点冗长。

      【讨论】:

      • 你需要一个额外的参数,例如go (n:ns) g' = case match n g' of ...
      猜你喜欢
      • 2013-12-29
      • 2011-01-10
      • 1970-01-01
      • 2014-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2020-05-19
      • 2023-03-07
      相关资源
      最近更新 更多