繁体   English   中英

当我尝试去除它时,为什么我的Haskell符号会中断?

[英]Why does my Haskell do-notation break when I try to desugar it?

我有来自99个Haskell问题的问题26的以下代码:

combinations :: Int -> [a] -> [[a]]
combinations 0 _  = return []
combinations n xs = do y:xs' <- tails xs
                       ys <- combinations (n-1) xs'
                       return (y:ys)

上面的代码按预期工作。 以下是我的主要功能和打印结果:

main = print $ combinations 2 "abcd"
-- Prints: ["ab","ac","ad","bc","bd","cd"]

作为一个学习练习,我试图“desugar”这样的记号

combinations :: Int -> [a] -> [[a]]
combinations 0 _  = return []
combinations n xs = tails xs >>= \(y:xs') ->
                    do
                        ys <- combinations (n-1) xs'
                        return (y:ys)

这会编译,但在运行时会出现以下错误:

PatternMatchFail: /home/.../test.hs:(46,34)-(49,37): Non-exhaustive patterns in lambda

这里发生了什么? 如何用>>=>>替换do-notation?

来自Haskell Wikibook

......与lambdas的片段与do块“大致相同”。 它不是一个精确的转换,因为符号添加了模式匹配失败的特殊处理。

考虑这个例子:

f xs = do
       (x:_) <- Just xs
       return x  

g xs = Just xs >>=
       \(x:_) -> return x

对于任何非空列表,这些功能都是相同的。 但是f []返回Nothing ,而g []返回的错误很像你得到的错误。

这是因为do记号不同的方式处理故障。 Monad类型类具有fail功能。 您正在使用列表monad,它通过返回空列表而失败。 Maybe monad通过返回Nothing实现它。 无论哪种方式,里面的模式匹配失败do记号用此功能,因此区别处理。

所以翻译它的正确方法是:

g xs = Just xs >>= 
       \xs' -> case xs' of
                 (x:_) -> return x
                 []    -> fail "some error"

暂无
暂无

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

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