我可以在这个表达式中取消糖的列表理解:
[(i,j) | i <- [1..4], j <- [i+1..4]]
这是输出:
[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
我如何使用 map ,过滤器等编写这段代码?
编辑
这里另一个:
[(i,j,k) | i <- [1..6], j <- [i+1..6],k <- [j+1..6]]
这是输出:
[(1,2,3),(1,2,4),(1,2,5),(1,2,6),(1,3,4),(1,3,5),(1,3,6),(1,4,5),(1,4,6),(1,5,6),(2,3,4),(2,3,5),(2,3,6),(2,4,5),(2,4,6),(2,5,6),(3,4,5),(3,4,6),(3,5,6),(4,5,6)]
最佳答案
列表推导(实际上是Monad推导)可以简化为do
表示法。
do i <- [1..4]
j <- [i+1..4]
return (i,j)
可以像往常一样将其删除:
[1..4] >>= \i ->
[i+1..4] >>= \j ->
return (i,j)
众所周知
a >>= \x -> return b
与fmap (\x -> b) a
相同。因此,这是一个中间的减糖步骤:[1..4] >>= \i ->
fmap (\j -> (i,j)) [i+1..4]
对于列表,
(>>=) = flip concatMap
和fmap = map
(flip concatMap) [1..4] (\i -> map (\j -> (i,j) [i+1..4])
flip
只是切换输入的顺序。concatMap (\i -> map (\j -> (i,j)) [i+1..4]) [1..4]
这就是您对Tsuyoshi的回答的总结。
第二个同样可以简化为:
concatMap (\i ->
concatMap (\j ->
map (\k ->
(i,j,k))
[j+1..6])
[i+1..6])
[1..6]