Haskell Type Signature Вопрос
-
28-09-2019 - |
Вопрос
Может кто-нибудь объяснить мне, почему эти функции имеют Разное количество аргументов и поведения, но Та же тип подписи, все же они оба правильные?
comp1 :: (a -> b) -> (b -> c) -> a -> c
comp1 f g = g.f
comp2 :: (a -> b) -> (b -> c) -> a -> c
comp2 f g x = g (f x)
Кроме того, почему Comp2 имеет
comp2 :: (a -> b) -> (b -> c) -> a -> c
вместо чего-то вроде
comp2 :: a -> (a -> b) -> (b -> c) -> a -> c
?
Спасибо.
Решение
comp2 f g x = g (f x)
синтаксический сахар для
comp2 = \f -> \g -> \x -> g (f x)
по аналогии
comp1 f g = g.f
это сахар для
comp1 = \f -> \g -> g.f
Определение .
является:
f1 . f2 = \x -> f1 (f2 x) -- Names of arguments have been changed to avoid confusion
Так что если мы вставем определение в обезьянущую форму comp1
, мы получили:
comp1 = \f -> \g -> \x -> g (f x)
Это точно так же, как обезьяна comp2
, Так что ясно, что определения эквивалентны.
Другие советы
comp1 f g = g.f
написано в бессмысленный стиль (не ссылаясь на точки, а к значения). Когда вы называете comp1
, неявно, к которому передается третий параметр g.f
, который является составом двух функций g
а также f
: (g.f) x
равняться g (f x)
, т.е. g
передается результат f x
. Отказ Нет параметра x
существует внутри comp1
потому что это неявно передано функции. (Вы могли думать о comp1
как частично применяется или карман Функция, если это заставляет вас чувствовать себя лучше.)
comp2
Тип спрашивает две функции, один из (a->b)
и другой (b->c)
, а также параметр типа a
. Отказ Нет необходимости ставить a ->
в его подписи.
Две функции действительно эквивалентны; Один просто использует некоторые трюки Haskell, чтобы быть более лаконичным.
Carrying.. Отказ Функция мульти-аргументов в ML и haskell, является просто синтаксическим сахаром для функции одноразового аргумента, которая возвращает функцию; Функция, которую она возвращается, принимает оставшиеся аргументы.