几周前我刚刚开始学习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之前,它是解决骑士旅游问题的一部分..有人可以解释它是如何工作的吗?
你必须贬低这种符号.首先写下类型:
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)
所以你看到它在两个元素列表上的嵌套折叠.展开折叠是留给读者的练习:)