Prelude中null
函数的定义如下:
null :: [a] -> Bool
null [] = True
null (_:_) = False
让我困惑的是定义的第三行,为什么写:
null(_:_) = False
而不是:
null any = False
是否与编译器优化有关?
答案 0 :(得分:5)
是否与编译器优化有关?
不,实际上可以说写null (_:_)
的效率低于null any
(如果编译器没有对此进行优化),因为现在你要求Haskell验证它确实是& #34;缺点&#34 ;.虽然如果编译器对数据类型进行一些簿记,但当然很容易对其进行优化。据我所知,大多数编译器,如ghc
和几乎所有编译器都不是由三岁孩子写的确实会这样做。
首先,编写wilcard _
(或将其命名为any
)更好不,因为列表的定义(以及任何其他数据类型可能会更改) 。虽然列表的可能性很小,但有人可能会重新定义列表。比如:
data [a] = [] | (a:[a]) | (Int///[a])
例如,后一种模式意味着列表重复多次。在这种情况下,编译器不是由一个三岁小孩写的:)会警告 null
的不完整模式:因此它会声称{未指定{1}}模式。然而,如果您使用通配符,它将回退到(_///_)
情况。
一般情况下,最好小心使用通配符:只有在你真的不关心函数的内容时,才应该使用通配符。