2014-11-01 2 views
1

Новый в Haskell, я чувствовал, как :t не хватает скобки для меня, чтобы правильно понять тип функцииОтсутствие скобок в интерпретации Haskell типа функции

, как это:

Prelude> :info flip 
flip :: (a -> b -> c) -> b -> a -> c -- Defined in ‘GHC.Base’ 

Я мог бы сказать: flip принимает одну функцию и возвращает другую функцию, заключая так:

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

или я мог бы сказать, flip является т принимая к одной функции и b и a и возвращающие элементы c

для довольно много типов функций у меня было такое чувство, я думаю, там должны быть какие-то правила, чтобы устранить эту неоднозначность

+0

В чем ваш вопрос в точности? –

ответ

6

На самом деле, это не является неоднозначность, это особенность!

Возьмите, например, оператор плюс, (+). Он имеет тип

(+)::Num a=>a->a->a 

Который вы можете рассматривать как функцию, которая принимает два числа и возвращает третий.

number 
     \ 
      ----> number 
    /
number 

Вы можете использовать это как this-

(+) 1 2 (-- evaluates to 3) 
or 
1 + 2 (-- evaluates to 3) 

или, вы можете использовать его как

(+)::Num a=>a->(a->a) 

который принимает один номер, и выводит полную функцию, чей домен и диапазон - это число, то есть Num a=>a->a.

number ------> <function> 

, например

(+) 1 (-- evaluates to incrementorFunc) 
....also written as (+ 1) 

где incrementorFunc функция, которая добавляет один к ряду (т.е. incrementorFunc = \x -> 1+x).

Теперь вы можете передать эту функцию для использования в другом месте в коде.

Эта двойственность встроена во все функции, поэтому в описании типа не требуется скобка. Эта особенность - одна из самых сильных сторон Хаскелла.

+0

Не знаете, что вы имели в виду под именем 'Num a => (a-> a) -> a'. Вы имеете в виду 'Num a => (a, a) -> a', который он сортирует ... – luqui

+0

@ luqui- Вы правы, я неаккуратно .... И вы правильно относитесь к тому, что я в основном имел в виду , Дайте мне несколько секунд, и я переделаю части этого. – jamshidh

2

Вам не нужны скобки, потому что между ними нет никакой разницы.

Пуристы скажут, что все функции Haskell принимают ровно один аргумент. Нет никаких функций с несколькими аргументами. Например:

map f [1..10] 

интерпретируется как:

(map f) [1..10] 

т.е. map применяется с аргументом f и результат подается с аргументом [1..10].

Эта интерпретация делает автоматическую работу карри в Haskell. В определенном смысле каррирование является иллюзией в Haskell - то есть мы видим map f, и мы видим каррину в форме map, так как существует только один аргумент. В действительности map принимает только один аргумент, поэтому map f полностью применяется.