![](/img/trans.png)
[英]Haskell: Rigid type variable error when pattern matching bind operator
[英]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.