【问题标题】:Haskell pattern match error with bind operatorHaskell 模式匹配错误与绑定运算符
【发布时间】:2015-06-17 16:48:17
【问题描述】:

我有一个任务,我被困在一个点上,我没有任何进展。 给定的是一个函数:

transpose :: [[a]] -> [[a]]
transpose []       =  []
transpose ([]:ls)  =  transpose ls
transpose ll       =  [h | (h:_) <- ll] : transpose [t |(_:t) <- ll]

我将一方面使用 do-notation 和另一方面使用 bind-operator 再次编写它。我可以使用 hd、tl 和 (:)。 我对 do-notation 解决方案没有问题,但绑定版本存在模式匹配问题。 这是我目前所拥有的:

transheadA ll = ll >>= \(h:_) ->
    return h

transtailA ll = ll >>= \(_:t) ->
    return t

transposeA :: [[a]] -> [[a]]
transposeA []       =  []
transposeA ([]:ls)  =  transposeA ls
transposeA ll       =  (transheadA ll : transposeA (transtailA ll))

do-notation 的相同样式有效,但使用绑定运算符时,我在 transheadA 处遇到模式匹配错误

\(h:_) -> ...

见:

transposeA [[1,2,3],[4,5,6],[7,8]]
[[1,4,7],[2,5,8],[3,6*** Exception: transpose.hs:(16,22)-(17,24): Non-exhaustive patterns in lambda

我一直在思考如何解决这个问题,但我不知道在哪里添加一个新模式来让这个工作。

编辑

当然,我只是想要提示。 直接解决方案既不是家庭作业的意义,也不是本板的意义。 谢谢你

编辑解决方案

感谢 CommuSoft,我想我可以解决这个问题。 我现在的解决方案如下:

transheadA :: [[a]] -> [a]
transheadA ll = ll >>= f
    where f (h:_) = return h
          f _     = fail []


transtailA :: [[a]] -> [[a]]
transtailA ll = ll >>= f
    where f (_:t) = return t
          f _     = fail []

transposeA :: [[a]] -> [[a]]
transposeA []       =  []
transposeA ([]:ls)  =  transposeA ls
transposeA ll       =  (transheadA ll : transposeA (transtailA ll))

【问题讨论】:

  • 当一个参数比其他参数短时,预期的行为是什么?您是否打算输入为 [[1,2,3], [4,5,6], [7,8,9]] ?或者可能只是一个错字?
  • 问题是不能确定列表中的所有元素都有一个头部,例如空数组[] 没有。 &lt;- 不仅仅是匹配,它还过滤。
  • 输入正确。比其他列表短的列表将被排除在外,根本不考虑结果。最好说,当没有更多元素进入结果列表列表时,应该附加空列表,或者更好的是,什么都不做。

标签: haskell pattern-matching bind


【解决方案1】:

这种方法存在一些问题:

  • transheadA 的签名应该不同于transtailA 的签名。

    transheadA :: [[a]] -> [a]
    transtailA :: [[a]] -> [[a]]
    
  • 由于您在列表推导中进行了一些模式匹配,因此您不能简单地在 lambda 表达式中使用它:模式可能会失败,在这种情况下,列表推导的一部分 fails 也是如此。您可以将其内联为:

    where f (h:_) = return h
          f _ = fail []
    

    然后你可以在绑定运算符&gt;&gt;=的一侧使用f。显然,这对如何编码事物有影响。对于每个这样的模式匹配(因此不是 x &lt;-x 单个变量),Haskell 可以编写这样的 fail(请注意 Haskell 不一定使用 list monad)。

  • 1234563在这种情况下,您需要将表达式的右侧替换为 [x] 而不是 x

根据上述提示,我已经设法自己修复了您对transpose 的实现。我希望这能澄清一两件事?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-18
    • 2017-08-10
    • 2018-12-14
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多