Haskell - 从句法糖翻译

Mar*_*ock 1 haskell syntactic-sugar

任务是翻译这个

f = do
    c <- [1 .. 200]
    b <- [1 .. 200]
    guard (c >= b)
    a <- [1 .. 200]
    guard (a >= b && (c^2 - a^2 == b^2))
    return (a,b, c)
Run Code Online (Sandbox Code Playgroud)

成为一个非糖的版本.

我想我已经弄清楚了大部分问题,但是我在中间遇到了一个我需要修复的问题才能继续.到目前为止,我有:

f = [1 .. 200] >>= \c ->
    [1 .. 200] >>= \b ->
    if (c >= b) 
        then [1 .. 200] >>= \a -> if (a >= b && (c^2 - a^2 == b^2)) 
                                      then return(a,b,c)
                                      else return ()
        else return ()
Run Code Online (Sandbox Code Playgroud)

哪个不编译.当我输入(a,b,c)返回时,它会编译,但显然它不再给出预期的结果.如何在else分支中返回"nothing"?

如果我输入((),(),())作为返回值,编译器会得到一个"没有实例(Num [a])来自文字'1'"

Dan*_*her 8

相反的return (),这是[()],你必须产生一个空的列表,所以else []或与通用guard的实现else mzero.

成功分支生成三元组列表[(Int,Int,Int)](或Integer,或其他Num类型),因此失败分支必须生成相同的内容.由于失败意味着没有找到三元组,它们将产生一个空列表.

注意,在[]monad中,return x只是[x]mzero(from MonadPlus)是一样的fail whatever,即[].

  • `guard`使用`mzero`,而不是`fail`. (2认同)

zch*_*zch 5

guard实际上并不是语法糖.这是一个功能Control.Monad.

guard :: MonadPlus m => Bool -> m ()
guard True  = return ()
guard False = mzero
Run Code Online (Sandbox Code Playgroud)

如果列表mzero[].在这里阅读更多:http://en.wikibooks.org/wiki/Haskell/MonadPlus