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

时间:2016-03-02 00:55:37

标签: 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

然后它问道:

  • 为什么不在这里将方程的顺序更改为head'帮助?
  • 如果将第一个等式更改为使用普通的可反射模式, head'的行为是否仍会与head的行为不同?如果 那怎么样?

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

1 个答案:

答案 0 :(得分: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 ⊥ = ⊥

head是标准库版本。 head'是wikibook的版本。 head1是交换了子句的版本。 head2是第一个模式是针对[]的可退款匹配的版本。 ⊥读作“底部”,表示非终止或例外计算,即undefined

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

konst ~() = ()

konst' () = ()

partialId ~(x:xs) = x:xs

partialId' (x:xs) = x:xs