2013-12-12 3 views
2

Возможно, я прошу что-то очень глупое, и ответ может быть очень простым, поскольку «разработчик выбрал его таким образом», но здесь я иду.Ошибка функциональной композиции Haskell

Чтобы добавить два номера, мы можем использовать любой стиль: (10+) 4 или 10 + 4 или (10 + 4).

, а если у нас есть две функции, скажем, add10 и multiply5 и компоновать их, чтобы сделать одну функцию из нее, скажем add10andMultiply5 тогда
add10.mul5 10, кажется, дает ошибку при
add10.mul5 $ 5 будет работать и
(add10.mul5) 5 будет работа и
add10andMultiply5 5 также будет работать.

Любые комментарии, почему первый не должен работать? Пожалуйста, просветите меня. Благодарю.

+4

'10 (+4)' не будет работать, потому что это означает «применить функцию' 10' к аргументу '(+4)', а '10' не является функцией. –

+0

Спасибо за указание. . Ты прав – Tanmay

ответ

4

Функциональный состав в Haskell имеет более низкий приоритет, чем применение функции. Таким образом, add10.mul5 10 разобран как add10 . (mul5 10). Теперь, тип . определяется как:

(.) :: (b -> c) -> (a -> b) -> a -> c 

Первый аргумент (add10) имеет тип Int -> Int, поэтому мы можем установить, что Ь Int, и, следовательно, . ожидает, что ее второй аргумент будет типа a -> Int. Но вместо этого он имеет тип Int. Добавление $ изменяет ассоциацию и означает, что вместо того, чтобы скомпоновать скомпонованную функцию, необходимо добавить композицию функции.

Все работает в вашем первом примере, потому что вы не составляете функции, вы просто применяете их. Эквивалент в этом случае будет пытаться сделать (10+) . 4, который вы также увидите.

7

Это проблема приоритета, или как тесно связаны разные операции.

В Haskell функциональное приложение имеет наивысший приоритет (самое жесткое связывание), за которым следует функциональная композиция, а затем функциональное приложение с $. Это немного, как арифметика, где экспоненцирование имеет наивысший приоритет, затем умножение, затем сложение, так что

1 + 2^4 * 3 + 4 * 3 

обрабатывается как

1 + ((2^4) * 3) + (4 * 3) 

В ваших примерах, у вас есть

add10 . mul5 10 

который будет проанализирован как

add10 . (mul5 10) 

, потому что приложение приложения привязывается к самому жесткому. Это не работает, потому что mul5 10 - это номер, а add10 - это функция, а композиция работает только между двумя функциями.

С другой стороны,

add10 . mul5 $ 10 

анализируется как

(add10 . mul5) $ 10 

потому, что функция композиция имеет более высокий приоритет, то приложение с $.

Смежные вопросы