2016-01-11 2 views
3

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

Что это означает в простых мирах:

add:: Integer -> Integer -> Integer 

Означает ли это, что два первых параметра Integer, а возвращаемое значение равно Integer?

Можете ли вы объяснить мне, как использовать стрелки для определения типа параметра или, по крайней мере, дать мне краткое описание этой функции?

ответ

11

Вкратце мы можем действительно ссылаться на add как функцию, которая принимает два Integer s и производит Integer. Однако, чтобы понять нотацию, вам нужно понять, что технически нет такой вещи, как функция, которая принимает два аргумента в Haskell.

Скорее каждая функция занимает ровно один аргумент и типа функции записывается a -> r где a типа аргумента и r является типом результата. Функция arrow является право-ассоциативной, что означает, что тип a -> (b -> c) может быть записан без круглых скобок как a -> b -> c.

Так Integer -> Integer -> Integer такая же, как Integer -> (Integer -> Integer), который говорит нам, что add это функция, которая принимает Integer и производит еще одну функцию типа Integer -> Integer. Это известно как currying и является обычным способом «кодировать» функции с несколькими аргументами в Haskell.

Для вызова такой каррированной функции, мы можем написать add 1 2, что, так как применение функции левоассоциативно, такой же, как (add 1) 2, первый вызывая add 1 получить функцию типа Integer -> Integer, а затем применять эту функцию к аргументу 2 ,

4

Как простая ментальная модель - да, вещь после последней стрелки - это тип возврата, а все остальное - параметры.

Подписи для 2-и-более-сложных функций выглядят так, потому что они на самом деле унарные функции, возвращающие еще одну 1-и-более важную функцию.

В вашем случае

add :: Integer -> (Integer -> Integer) 

Passing add аргумент дает

add 3 :: (Integer -> Integer) 

И add 3 4, поэтому просто Integer типа.

+4

Я думаю, ссылка на [карринг] (https://wiki.haskell.org/Currying) и [частичное применение] (HTTPS : //wiki.haskell.org/Partial_application) для деталей не повредит. – bereal

1

Короткий ответ: да, это именно то, что он означает. Последний тип - это возвращаемое значение, все остальные - аргументы.

Это по очень простой причине, а именно: в Haskell нет такой функции, как функция multi-agrument. Все функции являются единственными аргументами в отношении вероятности, общий тип функции - a -> b. Тогда у нас есть что-то похожее на многопараметрические функции благодаря currying.Все, что вам нужно, чтобы понять это в круглые скобки:

add :: Integer -> (Integer -> Integer) 

который гласит: add это функция, которая принимает Integer и возвращает функцию Integer -> Integer. Здесь все круглые скобки заключаются в правой части. Наоборот, когда вы подаете заявление, все круглые скобки сжать на левую руку размере, например, так:

(add 5) 6 

который гласит: применять add аргумента 5. Взамен вы получите функцию - затем примените эту функцию к 6 (конечным результатом будет 11). Мы могли бы одинаково хорошо определить его следующим образом:

add :: Integer -> (Integer -> Integer) 
add x = \y -> x + y 

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

Этот факт также, почему мы можем это сделать:

add5 :: Integer -> Integer 
add5 = (+5)