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)使用列表推导时是否存在隐含意义?
模式匹配失败在列表推导中特别处理.如果模式无法匹配,则删除该元素.因此,你只得到"hh"第三个列表元素,但因为元素与模式不匹配.
这是由于fail在模式无法匹配某个元素的情况下由列表推导调用的函数的定义:
fail _ = []
Run Code Online (Sandbox Code Playgroud)
这个答案的正确部分是礼貌kmc的#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)
是.当您通过模式匹配限定列表推导时,将过滤掉不匹配的值,删除示例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.
| 归档时间: |
|
| 查看次数: |
762 次 |
| 最近记录: |