删除语法糖:Haskell中的列表理解

Car*_*ess 15 haskell functional-programming list-comprehension list lazy-evaluation

我可以在这个表达式中解释列表理解:

[(i,j) | i <- [1..4], j <- [i+1..4]]
Run Code Online (Sandbox Code Playgroud)

这是输出:

[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
Run Code Online (Sandbox Code Playgroud)

我怎么能用地图,过滤器等编写那段代码?

编辑

这是另一个:

[(i,j,k) | i <- [1..6], j <- [i+1..6],k <- [j+1..6]]
Run Code Online (Sandbox Code Playgroud)

这是输出:

[(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)]
Run Code Online (Sandbox Code Playgroud)

Dan*_*ton 25

列表理解(事实上,Monad的理解)可以被贬低为do符号.

do i <- [1..4]
   j <- [i+1..4]
   return (i,j)
Run Code Online (Sandbox Code Playgroud)

像往常一样可以去除糖尿病:

[1..4]   >>= \i ->
[i+1..4] >>= \j ->
return (i,j)
Run Code Online (Sandbox Code Playgroud)

众所周知,它是a >>= \x -> return b一样的fmap (\x -> b) a.所以一个中间的脱离步骤:

[1..4] >>= \i -> 
fmap (\j -> (i,j)) [i+1..4]
Run Code Online (Sandbox Code Playgroud)

对于列表(>>=) = flip concatMap,和fmap = map

(flip concatMap) [1..4] (\i -> map (\j -> (i,j) [i+1..4])
Run Code Online (Sandbox Code Playgroud)

flip 只需切换输入的顺序.

concatMap (\i -> map (\j -> (i,j)) [i+1..4]) [1..4]
Run Code Online (Sandbox Code Playgroud)

这就是你如何结束Tsuyoshi的答案.


第二个可以同样被贬低为:

concatMap (\i ->
  concatMap (\j ->
    map       (\k ->
      (i,j,k))
    [j+1..6])
  [i+1..6])
[1..6]
Run Code Online (Sandbox Code Playgroud)