Замены скобок в этой функции:
isInteger x = x == fromInteger (round x)
с оператором знак доллара:
isInteger x = x == fromInteger $ round x
вызывает ошибку.
Каковы ограничения использования оператора $?
Замены скобок в этой функции:
isInteger x = x == fromInteger (round x)
с оператором знак доллара:
isInteger x = x == fromInteger $ round x
вызывает ошибку.
Каковы ограничения использования оператора $?
$
имеет крайне низкий приоритет, ниже ==
, ниже все. Попытка анализируется как
isInteger x = (x == fromInteger) $ (round x)
, который он пытается применить Bool
в качестве функции. Вы можете написать
isInteger x = x == (fromInteger $ round x)
но это на самом деле не сохраняет никаких круглых скобок; это просто сдвигает их.
Если вы действительно хотите, чтобы избавиться от скобок (или, по крайней мере, на самом деле переместить их в сторону), вы можете воспользоваться тем, что (-> r)
является аппликативным функтор, который вкратце означает, что f <*> g == \x -> f x (g x)
, Замена f
с (==)
и g
с fromInteger . round
, вы получите
isInteger = (==) <*> fromInteger . round
потому
x == fromInteger (round x) -> (==) x (fromInteger (round x))
-> (==) x ((fromInteger . round) x)
---- ---------------------
f x ( g x)
Это хорошее разъяснение, объясняющее вам объяснение Хаскелла: «вы можете представить себе, что $ является эквивалентом написания открывающих круглых скобок, а затем писать закрытие в правой части выражения». – Trajanson
Пока мы цитируем LYAH, я должен также упомянуть, что «[функции] редко используются с аппликативным стилем вне кода гольфа».Это умный, лаконичный и едва читаемый :) – chepner
@chepner Это похоже на читаемость, если вы думаете о нем как о монаде «Читатель». – PyRulez
Это начало принятого ответа на вопрос, который вы связаны в комментариях:
$ для избежания скобок. Все, что появляется после , будет иметь приоритет над всем, что приходит раньше.
Принимая это во внимание, isInteger x = x == fromInteger $ round x
становится isInteger x = (x == fromInteger) (round x)
, поэтому вы принимаете результат x == fromInteger
(который типа Bool
) и применить его к round x
. Это явно не имеет смысла.
Лучший вопрос SO не справляется с этой проблемой: http://stackoverflow.com/questions/940382/haskell-difference-between-dot-and-dollar-sign – Trajanson
Это просто оператор инфикса с низким приоритетом. Вы получите сообщение об ошибке по той же причине: '3 * 5 + 7' означает' (3 * 5) + 7', а не '3 * (5 + 7)'. –
@ DanielWagner вы можете определить «оператор инфикса», как вы понимаете этот термин? – Trajanson