2013-12-25 5 views
4

Я просто изучаю Haskell и функциональное программирование с помощью книги Ричарда Берда и натолкнулся на сигнатуру типа функции (.). А именнопонимание сигнатуры типа (.)

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

и связанное с ним определение

(f . g) x = f (g x) 

Я понимаю, что делает оператор, но я немного запутался о том, как читать сигнатуру типа. Говорит ли он, что (.) Принимает в качестве первого аргумента функцию типа (b -> c), затем возвращает функцию типа (a -> b) и, наконец, возвращает функцию типа (a -> c)? Правильно ли это читать подпись типа?

Кроме того, может ли это быть примером currying, где (.) Является карриной функцией, которая принимает два параметра? Или это не правильный способ подумать о карри?

ответ

12

Вы почти получили его, он принимает b -> c и возвращает функцию (a -> b) -> (a -> c), которая при задании (a -> b) возвращает функцию a -> c. Это может быть также полезно знать, что в Haskell, вы можете заключить оператор в круглые скобки и использовать его префикс так

f . g === (.) f g 

Теперь это легче увидеть Карринг

((.) f) g === f . g 

Наконец, обратите внимание, что этот тип подпись эквивалентна

(b -> c) -> (a -> b) -> a -> c 

С -> является правильным ассоциативным.

4

Вы можете прочитать подписи функции с несколькими аргументами, как это:

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

так, (f .) :: (a -> b) -> (a -> c)

Следующая та же:

foo :: a -> b -> c -> d -> e 

foo :: a ->(b ->(c ->(d -> e))) 

Функция (.) занимает 2 функции (a -> b) как параметры и вернуть их состав

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