繁体   English   中英

Haskell模式匹配错误与绑定运算符

[英]Haskell pattern match error with bind operator

我有一个任务,我被困在某个地方,我无法继续前进。 给出的是一个函数:

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

我将再次使用do标记和另一方面的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的样式相同,但是使用bind运算符时,我在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))

这种方法存在一些问题:

  • 的签名transheadA应该比一个不同的transtailA

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

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

    然后,可以在绑定运算符>>=的一侧使用f 显然,这对如何编码事物有影响。 对于每个这样的模式匹配隐式地表示(因此x <-x <- x而不是x <-所有变量都具有单个变量)Haskell可能会编写这样的fail (请注意,Haskell不一定使用list monad)。

  • 正如您可以在此处阅读的monad列表所示,您无需使用return ,尽管在这种情况下这不是什么大问题,但可以减少代码的长度。 在这种情况下,您需要将表达式的右侧替换为[x]而不是x

根据以上提示,我设法修复了您自己进行transpose的实现。 我希望这可以澄清一两件事?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM