Haskell wikibook中的无可辩驳/懒惰模式练习

Mik*_*nan 2 haskell pattern-matching lazy-evaluation strictness

在这里的一半......

https://en.wikibooks.org/wiki/Haskell/Laziness

...是一个练习,询问更改对head使用无可辩驳模式的函数的替代实现的影响.它提供了head'如下定义,指出它将始终undefined由于第一个等式的无可辩驳的匹配而返回:

head' :: [a] -> a
head' ~[]     = undefined
head' ~(x:xs) = x
Run Code Online (Sandbox Code Playgroud)

然后它问:

  • 为什么不改变方程的顺序来head'帮助这里?
  • 如果第一个等式被改为使用普通的可反复模式,那么行为head'仍然会不同于head?如果是这样,怎么样?

在GHC 7.8.4中,似乎更改顺序"帮助"至少使得此函数的行为类似于常规的部分版本head,尽管在空列表情况下有不同的例外.第二个问题的答案在我看来是"不",但考虑到"如果是这样,如何"的附录,我觉得我在这里也必须遗漏一些东西.任何人都可以开导我吗?不幸的是,页面上的解决方案链接并未涵盖此练习.

Der*_*ins 7

我不确定wikibook的意思是"帮助".你是正确的,改变顺序将使它的行为基本上像正常一样head.同样,你是正确的,使第一个模式可重复也会使它表现得像head.我要说这些问题很混乱; 他们肯定令人困惑.

我们可以通过计算验证这些答案(包括用GHC计算):

head [] = ?
head (x:xs) = x
head ? = ?

head' [] = ?
head' (x:xs) = ?
head' ? = ?

head1 [] = ?
head1 (x:xs) = x
head1 ? = ?

head2 [] = ?
head2 (x:xs) = x
head2 ? = ?
Run Code Online (Sandbox Code Playgroud)

head是标准库版本.head'是wikibook的版本.head1是交换了子句的版本.head2是第一个模式是refutable匹配的版本[].⊥被读作"底部"并表示非终止或异常计算,即undefined.

我所期望的是如下例子,其中可反驳和无可辩驳的模式之间存在细微但显着的差异:

konst ~() = ()

konst' () = ()

partialId ~(x:xs) = x:xs

partialId' (x:xs) = x:xs
Run Code Online (Sandbox Code Playgroud)