Карри функции F#

У меня есть вопрос, касающийся двух типов int -> (int -> int) и (int -> int) -> int. В чем разница между этими двумя?

Где-то здесь я читал, что первое можно интерпретировать как функцию, которая принимает int и возвращает функцию, которая принимает и int и возвращает int, что совпадает с int -> int -> int. Это правильно?

4 ответа

Решение

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

Тем не менее, оба они очень отличаются от (int -> int) -> int, который берет функцию из целых чисел в целые и возвращает целое число. Как уже упоминалось, единственный простой пример такой функции - применить данную функцию к определенному значению (например, fun (f:int->int) -> f 13).

Хороший вопрос, я подозреваю, что функционально нет большой разницы. Я потратил некоторое время, пытаясь понять, как вообще получить эти две подписи. (Джон Палмер let fun1 i = fun j -> i + j просто дает int -> int -> int для меня)

let add a b = a + b       // int -> int -> int
let inc a = add a         // int -> (int -> int)

Я не мог придумать необдуманный пример для второй подписи:

let foo fn : int -> fn 1  // (int -> int) -> int

(Это не дает прямого ответа на ваш вопрос, но может дать кому-то что-то, что можно пережевывать)

Я действительно не знаю F#, но это кажется довольно интуитивным (многие другие языки имеют те же понятия).

  1. Функция принимает int и возвращает функцию, которая принимает int и возвращает int
  2. Является ли функция, принимающая функцию, которая принимает int и возвращает int, и возвращает int

Первое было бы как функция карри.

Итак, давайте посмотрим, как будут выглядеть реализации:

первый

let func1 i = fun j -> i+j

это имеет подпись int -> (int -> int)

Обратите внимание, что func1 2 3 не должно работать

РЕДАКТИРОВАТЬ: Оказывается, из-за того, как ассоциативность работает, это на самом деле хорошо

но это отличается от

let func2 i j= i+j

который имеет тип int -> int -> int

Вот func2 1 2 Это хорошо

другой пример, который мы можем создать так:

let func4 a = a 1

это будет иметь подпись ('t->int) -> u выбирая бетон a буду работать. Обратите внимание, что func4 1 2 точно не скомпилируется

Другие вопросы по тегам