如何使用地图和过滤器实现列表理解?

Ket*_*tho 5 haskell functional-programming list-comprehension

双方mapfilter可以使用列表理解来实现:

map f xs    = [f x | x <- xs]
filter p xs = [x | x <- xs, p x] 
Run Code Online (Sandbox Code Playgroud)

我想用下面的例子来说明相反的情况:

[expr | p <- s]
Run Code Online (Sandbox Code Playgroud)

我到目前为止:

map (\p -> expr) s
Run Code Online (Sandbox Code Playgroud)

但这仅在模式匹配p成功对的所有元素时有效s。从某种意义上说,我首先要s使用与匹配的模式进行过滤p。自然地,我尝试调查这个问题,但是我没有找到不使用列表推导或LambdaCase的解决方案。

dup*_*ode 9

但这仅在模式匹配p成功对的所有元素时有效s

事实上:你描述的模式匹配的行为不能,一般来说,与实现mapfilter孤独。用这种术语表达理解仅在具有单个生成器且模式不会失败的更简单的理解情况下才能很好地工作。相反,列表理解是在Haskell报告中以表示的concatMap。特别是,有关生成器的条款涵盖了模式匹配失败的可能性:

--This is pseudo-Haskell; see the Report for the fine print.
[  e | p <- l,  Q ] = let ok p = [  e | Q ]
                          ok _ = []
                          in concatMap ok l
Run Code Online (Sandbox Code Playgroud)

匹配失败的处理对应于fail列表monad do-block的减重操作。