Рассмотрим выражение 10 / 2 / 5
. Это то же самое, что (10 / 2) / 5
или 10 / (2 / 5)
? Если вы интерпретируете /
как математическое деление, то первое верно, а второе ложно. Итак, вы видите, ответ на ваш вопрос «есть разница, но только иногда».
Типы противоположны. a -> b -> c
совпадает с a -> (b -> c)
и определенно не совпадает с (a -> b) -> c
.
Вы говорите, что не совсем уверены, когда это необходимо: ну, вот оно. Если аргумент вашей функции также является функцией, то это необходимо.
Рассмотрим map :: (a -> b) -> [a] -> [b]
. Это отличается от a -> b -> [a] -> [b]
, как видите, (a -> b)
указывает на определенный тип функции: функцию от типа a
до типа b
.
iterate :: (a -> a) -> a -> [a]
интереснее. Эта функция требует, чтобы типы входа и выхода функции в первом параметре были одинаковыми.
Вас может заинтересовать чтение карри и частичное применение. Один хороший ресурс среди многих: Узнайте о Haskell # Curried Functions