这怎么阻止工作?

isg*_*sgy 4 syntax haskell

几周前我刚刚开始学习haskell,我看到了这个:

moves = do
    f <- [(+), subtract]
    g <- [(+), subtract]
    (x, y) <- [(1, 2), (2, 1)]
    [f x *** g y]
Run Code Online (Sandbox Code Playgroud)

我还没有看到一个do块结束在list之前,它是解决骑士旅游问题的一部分..有人可以解释它是如何工作的吗?

Don*_*art 6

你必须贬低这种符号.首先写下类型:

import Control.Arrow

moves :: [(Integer, Integer) -> (Integer, Integer)]
moves = do
    f <- [(+), subtract]
    g <- [(+), subtract]
    (x, y) <- [(1, 2), (2, 1)]
    [f x *** g y]
Run Code Online (Sandbox Code Playgroud)

所以我们在[](list)monad中.

查找Monad []的定义:

instance  Monad []  where
    m >>= k             = foldr ((++) . k) [] m
    m >> k              = foldr ((++) . (\ _ -> k)) [] m
    return x            = [x]
Run Code Online (Sandbox Code Playgroud)

并将do notation翻译为bind并返回:

moves =
    [(+), subtract] >>= \f ->
    [(+), subtract] >>= \g ->
    [(1, 2), (2, 1)] >>= \(x,y) ->
    [f x *** g y]
Run Code Online (Sandbox Code Playgroud)

然后,最后,根据它们的定义重写绑定:

return列表

moves =
    [(+), subtract] >>= \f ->
    [(+), subtract] >>= \g ->
    [(1, 2), (2, 1)] >>= \(x,y) ->
    return (f x *** g y)
Run Code Online (Sandbox Code Playgroud)

>> =的定义

moves =
    foldr ((++) . (\f ->

            [(+), subtract] >>= \g ->
            [(1, 2), (2, 1)] >>= \(x,y) ->
            return (f x *** g y)

            )) [] [(+), subtract]
Run Code Online (Sandbox Code Playgroud)

>> =的定义

moves =
    foldr ((++) . (\f ->
        foldr ((++) . (\g ->
                [(1, 2), (2, 1)] >>= \(x,y) ->
                return (f x *** g y))
                ) [] [(+), subtract]
            )) [] [(+), subtract]
Run Code Online (Sandbox Code Playgroud)

>> =的定义

moves =
    foldr ((++) . (\f ->
        foldr ((++) . (\g ->
            foldr ((++) . (\(x,y) -> return (f x *** g y))
                    ) [] [(1, 2), (2, 1)]
                )) [] [(+), subtract]
            )) [] [(+), subtract]
Run Code Online (Sandbox Code Playgroud)

撤消退货:

moves =
    foldr ((++) . (\f ->
        foldr ((++) . (\g ->
            foldr ((++) . (\(x,y) -> [f x *** g y])
                    ) [] [(1, 2), (2, 1)]
                )) [] [(+), subtract]
            )) [] [(+), subtract]
Run Code Online (Sandbox Code Playgroud)

所以你看到它在两个元素列表上的嵌套折叠.展开折叠是留给读者的练习:)

  • 我已经知道列表monad do-understanding中发生了什么,但我发现带有`foldr`的desugared版本无法遵循.我不知道它应该如何帮助那些不知道发生了什么的人. (5认同)
  • 如果使用`concatMap f`而不是`foldr((++).f)[],可能会更容易理解. (2认同)