【问题标题】:What does the use of a colon between symbols in a parameter in a Haskell function definition do?在 Haskell 函数定义的参数中,在符号之间使用冒号有什么作用?
【发布时间】:2016-02-19 23:17:11
【问题描述】:

我一直在阅读Real World Haskell,并在第 2 章的练习中遇到了一个有趣的解决方案。

该练习要求读者构造一个行为类似于 Haskell 的 drop 的函数。一个solution 看起来像这样:

lastButOne :: [a] -> a
lastButOne (x:xs) = if length xs == 1
                    then x
                    else lastButOne xs

改进后的版本如下所示:

lastButOne :: [a] -> a
lastButOne (x1:[x2]) = x1
lastButOne (x:xs) = lastButOne xs

我很难理解中缀冒号在这里的作用。有人可以告诉我应该如何阅读这篇文章吗?

据我了解,elem:[b] 告诉 Haskell 将 elem 添加到 [b]

但是假设我定义了一个类似lastButOne (x:xs) 的函数。然后假设我有一个列表testCase = [p,q..r]。假设lastButOnetestCase 视为两个独立的对象,即[p][q..r],我是否正确?

如果是这样的,阅读lastButOne 的第一次迭代感觉非常直观。但是我仍然不明白lastButOne 的第二次迭代是如何工作的。

【问题讨论】:

标签: haskell recursion pattern-matching operators


【解决方案1】:

lastButOne (x:xs)... 只有 一个 参数,从函数的类型可以看出。 (x:xs) 是一种模式,它匹配具有至少一个元素的列表。第一个元素命名为x,列表的其余部分命名为xs

【讨论】:

    【解决方案2】:

    灯泡。

    lastButOne :: [a] -> a
    lastButOne (x1:[x2]) = x1
    lastButOne (x:xs) = lastButOne xs
    

    这段代码的工作方式如下:Haskell 检查模式(x1:[x2]) 与传递给lastButOne 的对象。 (x1:[x2]) 是一个匹配单例列表的模式,该列表前面带有与 x2 相同类型的项目。像[1,2] 这样的列表适合这种模式,可以写成1:[2],而像[1,2,3] 这样的列表 适合这种模式。由于第一个模式匹配失败,Haskell 陷入了“catch-all”模式,x:xs

    【讨论】:

      【解决方案3】:

      : 操作符通常称为cons(取自 Lisp 用语)。 (x:xs) 是常见的 Haskell 模式匹配,其中 (x:xs)[a]x 是列表的头部/第一个元素(a),xs 是尾部/其余部分列表([a]as 的列表)。

      Prelude> let a = (1:2:3:[])
      Prelude> let b = (1:[2,3])
      Prelude> a
      [1,2,3]
      Prelude> b
      [1,2,3]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 2012-08-30
        • 2019-11-13
        • 2014-11-24
        • 2010-12-03
        相关资源
        最近更新 更多