为什么Haskell Prelude中的null函数定义如此奇怪?

时间:2017-10-11 15:03:05

标签: haskell functional-programming compiler-optimization

Preludenull函数的定义如下:

null             :: [a] -> Bool
null []          =  True
null (_:_)       =  False

让我困惑的是定义的第三行,为什么写:

null(_:_)        = False

而不是:

null any = False

是否与编译器优化有关?

1 个答案:

答案 0 :(得分:5)

  

是否与编译器优化有关?

不,实际上可以说写null (_:_)的效率低于null any(如果编译器没有对此进行优化),因为现在你要求Haskell验证它确实是& #34;缺点&#34 ;.虽然如果编译器对数据类型进行一些簿记,但当然很容易对其进行优化。据我所知,大多数编译器,如ghc和几乎所有编译器都不是由三岁孩子写的确实会这样做。

首先,编写wilcard _(或将其命名为any)更好,因为列表的定义(以及任何其他数据类型可能会更改) 。虽然列表的可能性很小,但有人可能会重新定义列表。比如:

data [a] = [] | (a:[a]) | (Int///[a])
例如,后一种模式意味着列表重复多次。在这种情况下,编译器不是由一个三岁小孩写的:)会警告 null 不完整模式:因此它会声称{未指定{1}}模式。然而,如果您使用通配符,它​​将回退到(_///_)情况。

一般情况下,最好小心使用通配符:只有在你真的不关心函数的内容时,才应该使用通配符。