Exception Haskell:对组合的列表理解

Exception Haskell:对组合的列表理解,exception,haskell,list-comprehension,Exception,Haskell,List Comprehension,受此启发。我在玩从列表理解到组合风格的转换功能。我发现了一些有趣的东西 -- 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 Compre

受此启发。我在玩从列表理解到组合风格的转换功能。我发现了一些有趣的东西

-- 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 
——示例1:列表理解
*Main>[x |(x:|)地图头[“嗨”,“你好”,“你好”]
“hh***例外:前奏。标题:空列表
--例3:列表理解(翻译自例2)

*Main>[head xs | xs是。当您通过模式匹配来限定列表理解时,不匹配的值将被过滤掉,从而消除示例1中的空列表。在示例3中,空列表与模式
xs
匹配,因此不被过滤,然后
head xs
失败。模式匹配的要点是组件选择的构造函数识别

您可以通过无可辩驳的模式实现相同的可疑效果,在没有歧视的情况下懒洋洋地执行选择

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

Prelude>[x |(~(x:|))模式匹配失败是在列表理解中特别处理的。如果模式不匹配,元素将被删除。因此您只会得到第三个列表元素的
“hh”
,但第三个列表元素没有,因为元素与模式不匹配

这是由于定义了
fail
函数,当模式与某些元素不匹配时,列表理解会调用该函数:

fail _ = []
这个答案的正确部分是由哈斯克尔名声的kmc提供的。所有的错误都是我的,不要怪他。

见哈斯克尔报告中的。所以基本上

[x|(x:_)<-["hi","hello",""]]
注意:由于列表理解可以转换为
do
表达式,因此
do
表达式也会发生类似的情况,如中所述。因此,以下内容也会产生相同的结果:

do (x:_)<-["hi","hello",""]
   return x

do(x:\)非常奇特。还要注意的是,更“直译”的单子翻译失败:
[“嗨”,“你好”,“你好]”]>=(\(x:\)->返回x)
“lambda中的非穷举模式”注意,
do(x:\)也要注意,
[头部s |顺便说一句,如果你觉得需要模仿的话(偶尔有用)列表理解之外的行为,通过声名狼藉的诡计实现。例如,
Mapmaybay(spoon.head)[“嗨”,“你好”,“你好”][/code>给出了
“hh”
。因此它字面上翻译为
[x |(x:|)x的字面翻译为
[x |(x:|>=\s->{x:|->[x]|->的case s->
。如何将
fail
应用于
map head[“hi”,“hello”,“”“]
?@snmcdonald:首先,你不会将
head
映射到列表上,而是一个调用
fail
的函数,而不是为空列表未定义的函数。例如,
concatMap(\s->如果s=[],那么[]else[head s])[“hi hello”“,”“]
产生
“hh”
@snmcdonald请参阅我对猪倌回答的评论,以澄清翻译列表理解时如何产生
fail
。@David V:通过Monad的
fail
方法,该方法仅用于此目的(do符号中的模式匹配失败).参见丹尼尔·瓦格纳对养猪工人答案的评论。
do (x:_)<-["hi","hello",""]
   return x