F # Функции против значений

Это довольно простой вопрос, и я просто хотел проверить, что то, что я делаю, и как я интерпретирую F #, имеет смысл. Если у меня есть утверждение

let printRandom = x = MyApplication.getRandom() printfn "%d" x x 

Вместо того, чтобы создавать printRandom как функцию, F # запускает его один раз, а затем присваивает ему значение. Итак, теперь, когда я вызываю printRandom, вместо того, чтобы получать новое случайное значение и печатать его, я просто получаю все, что было возвращено в первый раз. Я могу обойти это, определяя его как таковое:

 let printRandom() = x = MyApplication.getRandom() printfn "%d" x x 

Является ли это правильным способом провести это различие между функциями и значениями без параметров? Для меня это кажется менее идеальным. Имеет ли это последствия в каррировании, композиции и т. Д.?

4 Solutions collect form web for “F # Функции против значений”

Правильный способ взглянуть на это состоит в том, что F # не имеет таких функций, как функции без параметров. Все функции должны принимать параметр, но иногда вам все равно, что это такое, поэтому вы используете () (одноэлементное значение единицы типа). Вы также можете сделать такую ​​функцию:

 let printRandom unused = x = MyApplication.getRandom() printfn "%d" x x 

или это:

 let printRandom _ = x = MyApplication.getRandom() printfn "%d" x x 

Но () используется по умолчанию, чтобы выразить, что вы не используете параметр. Он выражает этот факт вызывающему, потому что тип – unit -> int not 'a -> int ; а также читателю, потому что сайт вызова – printRandom () not printRandom "unused" .

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

Самый распространенный способ написания вызовов с помощью модуля, кстати, – с пространством, особенно у нечетных родственников F #, таких как Caml, SML и Haskell. Это потому, что () – одноэлементное значение, а не синтаксическая вещь, как в C #.

Ваш анализ правильный.

Первый экземпляр определяет значение, а не функцию. Я признаю, что это поймало меня несколько раз, когда я начал с F #. Исходя из C #, кажется очень естественным, что выражение присваивания, которое содержит несколько операторов, должно быть лямбдой и, следовательно, оценкой задержки.

В F # это не так. Заявления могут быть почти произвольно вложенными (и это сказывается на наличии локально ограниченных функций и значений). Как только вам станет комфортно, вы начинаете рассматривать это как преимущество, так как вы можете создавать функции и продолжения, недоступные для остальной функции.

Второй подход – это стандартный способ создания функции, логически не принимающей аргументов. Я не знаю точной терминологии, которую команда F # использовала бы для этого объявления, хотя (возможно, функция принимает один аргумент unit типа). Поэтому я не могу прокомментировать, как это повлияет на карри.

Является ли это правильным способом провести это различие между функциями и значениями без параметров? Для меня это кажется менее идеальным. Имеет ли это последствия в каррировании, композиции и т. Д.?

Да, то, что вы описали, правильно.

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

 // val contains : string -> bool let contains = let people = set ["Juliet"; "Joe"; "Bob"; "Jack"] fun person -> people.Contains(person) // val contains2 : string -> bool let contains2 person = let people = set ["Juliet"; "Joe"; "Bob"; "Jack"] people.Contains(person) 

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

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

 let foo = printfn "This runs at startup" (fun () -> printfn "This runs every time you call foo ()") 

Я просто написал сообщение в блоге об этом на http://blog.wezeku.com/2010/08/23/values-functions-and-a-bit-of-both/ .

Interesting Posts

В MVC3 Razor, как мне получить html визуализированного представления внутри действия?

Как предотвратить несанкционированный доступ к моей базе данных Firebase?

Сделать Google Chrome с определенным профилем пользователя в качестве браузера по умолчанию.

Android – NullPointerException в SearchView в панели действий

Как ссылаться на константы в EL?

Как вы получаете встроенный инструмент сравнения Eclipse, чтобы игнорировать различия в пробелах?

Google Chrome теряет (не показывает) сохраненный пароль после обновления

Нумерация строк внутри групп в кадре данных

Отладка и запуск Angular2 с помощью Visual Studio Code?

Можете ли вы найти все classы в пакете с использованием отражения?

В чем разница между% и %% в файле cmd?

Как я могу просмотреть список всех пользователей на экране входа в систему?

Как resize разделенных экранов emacs?

Как удалить Candy Crush Saga из Windows 10?

Исправлена ​​ошибка инициализации ffmpeg drawtext

Давайте будем гением компьютера.