2016-12-08 12 views
16

Выполненные функции в F #. Я получаю бит, где передача в подмножестве параметров дает функцию с пресетами. Я просто задавался вопросом, не отличается ли все параметры. Например:Когда вычисляются вызовы функций F #; лениво или сразу?

let addTwo x y = x + y 
let incr a = addTwo 1 
let added = addTwo 2 2 

incr - это функция, принимающая один аргумент. Есть added int или функция? Я могу представить себе реализацию, где «добавление» оценивается лениво только при использовании (например, «Шредингера» при открытии коробки). Есть ли гарантия того, когда добавление выполняется?

+0

Рассмотрите возможность редактирования названия вопроса, см. [Ask]. –

+0

Спасибо всем, кто прояснил это для меня. – Benboy

ответ

12

F # является жадно оценивали язык, поэтому сразу оценить выражение, как addTwo 2 2 до значения типа int.

Haskell, напротив, лениво оценивается. Выражение типа addTwo 2 2 не будет оцениваться до тех пор, пока значение не понадобится. Однако тип выражения все равно будет единственным целым числом. Тем не менее, такое выражение, несмотря на его лень, не рассматривается как функция; в Haskell такое неоценимое выражение называется thunk. Это в основном просто означает «произвольно сложное выражение, которое еще не оценено».

18

added не является функцией; это просто значение, которое вычисляется и привязывается к имени на месте. Функция всегда требует хотя бы одного параметра; если нет ничего полезного, чтобы пройти, это было бы unit() значение:

let added() = addTwo 2 2 
+0

Другим вариантом является использование ленивого ключевого слова: '' let added = lazy (addTwo 2 2) ''. Таким образом, значение будет оцениваться ленивым, но только один раз. – Gustavo

12

прирастить функция принимает один аргумент. Добавлен int или функция?

added, в данном случае, является именованным связыванием, которое оценивается как int. Это не функция.

Я могу представить себе реализацию, в которой «добавленная» оценивается лениво только при использовании (например, Шотринге «Кота» при открытии коробки). Есть ли гарантия того, когда добавление выполняется?

Приложение будет выполнено немедленно при связывании. Лены нет.

Как explained by TeaDrivenDev, вы можете изменить added быть связана функция вместо связанного значения, добавив параметр, который может быть unit:

let added() = addTwo 2 2 

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

let result = added() // Call the function, bind output to result 
2

Нет. Но да. Но на самом деле, нет.

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

Но F # отличается. Поскольку это довольно прагматичное сочетание императивного и функционального программирования, результат не является функцией [1]. Вместо этого это значение, как локальное в C#. Это не детализация реализации - на самом деле это часть спецификации F #. У этого есть недостатки - это означает, что у него может быть двусмысленное определение, где определение может быть либо значением, либо определением функции (14.6.1).

[1] - Хотя в чистой функциональной программе вы не можете сказать разницу - это то же самое, что просто делать замену функции с кешированным значением, что совершенно законно.