Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 去除句法糖分:Haskell中的列表理解_List_Haskell_Functional Programming_List Comprehension_Lazy Evaluation - Fatal编程技术网

List 去除句法糖分:Haskell中的列表理解

List 去除句法糖分:Haskell中的列表理解,list,haskell,functional-programming,list-comprehension,lazy-evaluation,List,Haskell,Functional Programming,List Comprehension,Lazy Evaluation,我是否可以取消此表达式中的列表理解: [(i,j) | i <- [1..4], j <- [i+1..4]] 如何使用map、filter等编写这段代码 编辑 这里是另一个: [(i,j,k) | i <- [1..6], j <- [i+1..6],k <- [j+1..6]] 红色代码为: concatMap (\i -> concatMap (\j -> (i, j) : []) [i+1..4]) [1..4] 可以重构为Ito Tsuy

我是否可以取消此表达式中的列表理解:

[(i,j) | i <- [1..4], j <- [i+1..4]]
如何使用map、filter等编写这段代码

编辑

这里是另一个:

[(i,j,k) | i <- [1..6], j <- [i+1..6],k <- [j+1..6]]
红色代码为:

concatMap (\i -> concatMap (\j -> (i, j) : []) [i+1..4]) [1..4]
可以重构为Ito Tsuyoshi的答案。

列表理解(事实上,单子理解)可以分解为
do
符号

doi=\i->
[i+1..4]>>=\j->
返回(i,j)
众所周知,
a>=\x->returnb
fmap(\x->b)a
相同。因此,中间脱糖步骤:

[1..4]>=\i->
fmap(\j->(i,j))[i+1..4]
对于列表,
(>>=)=flip-concatMap
,以及
fmap=map

(翻转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->
映射(\k->
(i,j,k))
[j+1..6])
[i+1..6])
[1..6]

据我所知,还有另一个翻译方案,是由于瓦德勒

这将使:

let
    lc_outer (x:xs) = let lc_inner (y:ys) = (x,y) : lc_inner ys
                          lc_inner []     = lc_outer xs
                      in lc_inner [x+1.. 4]
    lc_outer [] = []
in  lc_outer [1..4]
这种转换避免了在最内层构建不必要的单例列表,这些单例列表需要在以后使用concatMap进行展平

concatMap (\i -> map (\j -> (i, j)) [i+1 .. 4]) [1 .. 4]
concatMap (\i -> concatMap (\j -> (i, j) : []) [i+1..4]) [1..4]
let
    lc_outer (x:xs) = let lc_inner (y:ys) = (x,y) : lc_inner ys
                          lc_inner []     = lc_outer xs
                      in lc_inner [x+1.. 4]
    lc_outer [] = []
in  lc_outer [1..4]