Хотя функции должны быть идентичны, есть разница в том, как они применяются. С первым определением isFactor
полностью применяется на сайте вызова isFactor x
. Во втором определении это не так, потому что теперь isFactor
явно принимает два аргумента.
Даже минимальной оптимизации достаточно для того, чтобы GHC видел это и создавал идентичный код для обоих, однако, если вы компилируете с -O0 -ddump-simpl
, вы можете определить, что без оптимизации это будет иметь значение (по крайней мере, для ghc-7.2. 1, YMMV с другими версиями).
С первым isFactor
GHC создает одну функцию, которая передается в качестве предиката в «GHC.List.Filter», с вызовами mod 10000000
и (==)
. Что касается второго определения, то вместо этого происходит то, что большинство вызовов в isFactor
являются ссылочными ссылками на функции класса и не разделяются между несколькими вызовами isFactor
. Так что есть много лишних словарных слов, которые совершенно не нужны.
Это почти никогда не является проблемой, потому что даже настройки компилятора по умолчанию оптимизируют его, однако runhaskell, по-видимому, даже не делает так много. Несмотря на это, я иногда структурировал код как someFun x y = \z ->
, потому что я знаю, что someFun
будет применен частично, и это был единственный способ сохранить совместное использование вызовов (т. Е. Оптимизатор GHC не был достаточно умным).