Haskell:列出对组合的理解

8 haskell list-comprehension exception

灵感来自这篇文章.我正在玩从列表理解到组合风格的翻译功能.我找到了有趣的东西.

-- Example 1: List Comprehension 
*Main> [x|(x:_)<-["hi","hello",""]]
"hh"

-- Example 2: Combinatory
*Main> map head ["hi","hello",""]
"hh*** Exception: Prelude.head: empty list

-- Example 3: List Comprehension (translated from Example 2)
*Main> [head xs|xs<-["hi","hello",""]]
"hh*** Exception: Prelude.head: empty list 
Run Code Online (Sandbox Code Playgroud)

看起来奇怪的是,示例1没有抛出异常,因为(x:_)模式匹配其中一个定义head.filter (not . null)使用列表推导时是否存在隐含意义?

Fre*_*abe 7

模式匹配失败在列表推导中特别处理.如果模式无法匹配,则删除该元素.因此,你只得到"hh"第三个列表元素,但因为元素与模式不匹配.

这是由于fail在模式无法匹配某个元素的情况下由列表推导调用的函数的定义:

fail _ = []
Run Code Online (Sandbox Code Playgroud)

这个答案的正确部分是礼貌kmc#haskell名声.所有的错误都是我的,不要责怪他.

  • @snmcdonald:你不会首先将`head`映射到列表上,而是将一个函数调用`fail`而不是未定义为空列表.例如,`concatMap(\ s - > if s == [] then [] else [head s])["hi","hello",""]`产生`"hh"`. (2认同)

new*_*cct 7

请参阅Haskell报告中有关列表推导的部分.所以基本上

[x|(x:_)<-["hi","hello",""]]
Run Code Online (Sandbox Code Playgroud)

被翻译为

let ok (x:_) = [ x ]
    ok _     = [ ]
in concatMap ok ["hi","hello",""]
Run Code Online (Sandbox Code Playgroud)

PS由于列表推导可以转换为do表达式,因此表达式也会发生类似的事情do,详见do表达式一节.所以以下内容也会产生相同的结果:

do (x:_)<-["hi","hello",""]
   return x
Run Code Online (Sandbox Code Playgroud)


pig*_*ker 6

是.当您通过模式匹配限定列表推导时,将过滤掉不匹配的值,删除示例1中的空列表.在示例3中,空列表与模式匹配,xs因此未过滤,然后head xs失败.模式匹配的关键是构造函数歧视与组件选择的安全组合!

你可以用无可辩驳的模式实现同样的可疑效果,懒散地执行选择而不受歧视.

Prelude> [x|(~(x:_))<-["hi","hello",""]]
"hh*** Exception: <interactive>:1:0-30: Irrefutable pattern failed for pattern (x : _)
Run Code Online (Sandbox Code Playgroud)

列表解析整齐打包的用途map,concat以及由此filter.

  • `[x |.的字面翻译 (x:_)< - ["hi","hello",""]]`是`["hi","hello",""] >> =\s - > {x:_ - 的案例> [x]; _ - >失败"无穷无尽的模式匹配"}`. (9认同)