为什么当我试图解除它时,我的Haskell do-notation会打破? [英] Why does my Haskell do-notation break when I try to desugar it?

查看:124
本文介绍了为什么当我试图解除它时,我的Haskell do-notation会打破?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码来自 99个Haskell问题中的第26个问题

 组合:: Int  - > [a]  - > [[a]] 
组合0 _ =返回[]
组合n xs = do y:xs'< - tails xs
ys < - combination(n-1)xs'
return(y:ys)

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

  main =打印$组合2abcd
- 打印:[ab,ac,ad,bc,bd,cd]

作为学习练习,我尝试解除注释,如下所示:

 组合:: Int  - > [a]  - > [[a]] 
组合0 _ =返回[]
组合n xs = tails xs>> = \(y:xs') - >
do
ys< - 组合(n-1)xs'
返回(y:ys)

编译时,运行时出现以下错误:

pre $ PatternMatchFail:/ home / ... / test.hs:(46,34) - (49,37):lambda中的非穷举模式

这里发生了什么?我该如何用>> = >>

解决方案

Haskell Wikibook


...带有lambdas的片段与do块大致等价。它不是一个精确的翻译,因为这个符号添加了对模式匹配失败的特殊处理。


考虑这个例子:

  f xs = do 
(x:_)< - 只需xs
返回x

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

对于任何非空列表,这些函数是相同的。但是 f [] 返回 Nothing g [] 返回一个很像你所得到的错误。



这是因为 do 符号处理失败的方式不同。 Monad typeclass具有失败函数。您正在使用列表monad,通过返回一个空列表失败。 Maybe monad通过返回 Nothing 来实现它。无论采用哪种方式, do 表示法中的模式匹配失败都由此函数处理,因此是差异。



正确的翻译方式是:

  g xs = Just xs>> = 
\xs ' - > $ x $ b(x:_) - >的情况x' return x
[] - >失败一些错误


I have the following code from Problem 26 of the 99 Haskell problems:

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

The above code works as expected. Below is my main function and the printed results:

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

As a learning exercise I tried to "desugar" the do-notation like so:

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

This compiles, but gives the following error at runtime:

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

What is going on here? How can I replace the do-notation with >>= and >>?

解决方案

From the Haskell Wikibook:

... the snippet with lambdas was "broadly equivalent" to the do block. It is not an exact translation because the do notation adds special handling of pattern match failures.

Consider this example:

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

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

For any non-empty list, these functions are identical. But f [] returns Nothing, and g [] returns an error much like the one you're getting.

This is because the do notation handles failure differently. The Monad typeclass has a fail function. You're using the list monad, which fails by returning an empty list. The Maybe monad implement it by returning Nothing. Either way, the pattern match failure inside the do notation is handled with this function, hence the difference.

So the correct way to translate it would be:

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

这篇关于为什么当我试图解除它时,我的Haskell do-notation会打破?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆