Предполагаемые сигнатуры карри в F # - PullRequest
1 голос
/ 21 сентября 2019

В этой статье эта функция

let adderGenerator numberToAdd = (+) numberToAdd

имеет сигнатуру этого типа

int -> (int -> int)

Однако, когда я создаю эту функцию, предполагаемая сигнатура типа

int -> int -> int
  1. Отличаются ли эти подписи типов?
  2. Если нет, то как я могу аннотировать мой adderGenerator, чтобы он имел первую подпись типа?

Редактировать 1
Это лучшее, что я мог придумать на данный момент:

type Generator = int -> (int -> int)
let adderGenerator: Generator = (+)

Мне не нравится, как это заставляет adderGenerator принимать стиль без очков.

Редактировать 2
Кажется, это работает:

let adderGenerator numberToAdd : (int -> int) = (+) numberToAdd

1 Ответ

3 голосов
/ 22 сентября 2019

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

Эти три формы с полным аннотированным типом эквивалентны:

let adderGenerator : int -> int -> int =
    (+)

let adderGenerator (numberToAdd : int) : int -> int =
    (+) numberToAdd

let adderGenerator : int -> int -> int =
    fun numberToAdd -> (+) numberToAdd

Первая форма является просто псевдонимом для + и просто повторяет ее тип.

Вторая форма - это объявление функции, которая аннотирует тип аргумента и тип возвращаемого значения отдельно.

Третья форма - это переменная, которой назначена анонимная функция.

Однако, только одно явное указание аргумента кажется мне немного странным.Вы можете полностью избежать частичного применения, сделав оба аргумента явными:

let adderGenerator (a : int) (b : int) : int =
    (+) a b

let adderGenerator : int -> int -> int =
    fun a b -> (+) a b
...