Почему мы показываем несколько аргументов со стрелками и возвращаемый тип со стрелкой? - PullRequest
4 голосов
/ 01 октября 2019

Например, в документах по основам вяза:

(/) : Float -> Float -> Float

Это говорит о том, что / - это функция, которая принимает число с плавающей точкой, а другое число с плавающей точкой и возвращает число с плавающей точкой.

Почемуне будет ли это так:

(/) : (Float, Float) -> Float

Например, что кажется более интуитивным.

Есть ли для этого особая причина? Это также, как типы аннотируются в Haskel также.

https://package.elm -lang.org / packages / elm / core / latest / Basics

РЕДАКТИРОВАТЬ: Это имеетответили, но я также нашел это в документации для Elm: https://guide.elm -lang.org / appendix / function_types.html

Ответы [ 2 ]

9 голосов
/ 01 октября 2019

Технически Elm не имеет функций более одного аргумента. Тип Float -> Float -> Float (который совпадает с Float -> (Float -> Float), поскольку -> ассоциирован справа) представляет функцию, которая принимает Float и возвращает другую функцию, которая принимает другое значение с плавающей запятой. Затем вызов типа (/) a b (который совпадает с ((/) a) b, поскольку приложение функции является левоассоциативным) сначала применяет функцию (/) к a, а затем применяет результирующую функцию к b.

Обратите внимание, что вы также можете просто применить / к одному аргументу, не применяя результат сразу ко второму аргументу: например, inv = (/) 1 определит функцию inv, которая действует так же, как inv x = 1 / x.

(Float, Float) -> Float будет типом функции, которая принимает кортеж, содержащий два числа с плавающей точкой. Вы можете определить функцию с этим типом следующим образом:

f: (Float, Float) -> Float
f (x,y) = ...

И затем вы можете вызвать ее как f (arg1, arg2), где arg1 и arg2 являются числами с плавающей запятой или f tup, где tup являетсякортеж из двух поплавков.

5 голосов
/ 01 октября 2019

В функциональном программировании проще использовать версию, которая возвращает другие функции, поэтому, когда вы видите (/) : Float -> Float -> Float, это означает, что вы можете передать один аргумент и получить функцию Float -> Float обратно. Таким образом, в результате нет никакой разницы в результате (при условии, что вы передадите оба аргумента).

Этот метод перехода от версии кортежа (неиспользованной) к функциональной версии (карри) называется каррированием и широко используется и станетинтуитивно понятен после практики. Я не знаком с elm, но в Haskell вы можете легко перейти от карри версии и обратно:

f :: a -> (b -> c)     -- (which can also be written as    f :: a -> b -> c )
g :: (a, b) -> c

f = curry g -- transform argument from tuple to functions
g = uncurry f -- transform function arguments to tuple

Так что, если вы примените функцию f только к одному аргументу, вы получите функцию, котораяможет быть использован повторно. Проверьте Haskell wiki для более подробной информации. В отличие от функции, которая ожидает кортеж, повторное использование будет ограничено. Также посмотрите раздел Частичное приложение в вики, чтобы понять, почему это важно.

add2 :: Integer -> Integer -> Integer
add2 a b = a + b

add5 :: Integer -> Integer
add5 b = add2 5 b -- add2 is re-used
...