Вопрос

В настоящее время читаю серию постов в блоге о F #, ориентированных на программиста C #.Прямо сейчас я закончил читать часть 3 ( http://www.jelovic.com/weblog/?p=220 ) и остаюсь озадаченным.

Разница между

пусть readLine = Консоль.ReadLine ()

и

пусть readLine () = Консоль.ReadLine ()

достаточно ясно, но зачем нужно указывать две фигурные скобки - () - в следующей строке:

пусть печатается (текст :строка) () = Консоль.Текст строки записи

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

пусть печатается (текст :строка) = Консоль.Текст строки записи

Кроме того, следующая строка имела для меня мало смысла

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

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

спасибо вам всем за ответы, теперь мне все ясно.Что касается цитаты, то мы оставим ее в покое.

Это было полезно?

Решение

Введение. Я думаю, что полезно сначала обсудить разницу в простом примере, поскольку это помогает понять, что такое "единица измерения".Первое объявление создает строковое значение (и немедленно вызывает ReadLine чтобы получить входные данные от пользователя):

> let readLine = Console.ReadLine ();;
val readLine : string

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

Параметр "unit" - это просто способ создания функции, которая принимает что-то в качестве аргумента."Единица измерения" имеет только одно значение, записанное в виде (), поэтому он не представляет никакой информации - просто факт наличия некоторого параметра:

> let readLine () = Console.ReadLine ();;
val readLine : unit -> string

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

> let print (text : string) () = Console.WriteLine text 
val print : string -> unit -> unit

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

print "Hello" ()

Даже без дополнительного параметра "единица измерения" это была бы функция (в отличие от значения), поэтому добавление дополнительного параметра не помогает (вы всегда создаете функцию, которую можно вызывать для печати разных строк).

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

let f = print "Hello" // doesn't print anything
f ()                  // prints "Hello"
f ()                  // prints "Hello" again!

Итак, компилятор позволяет вам использовать "единичные" значения как любые другие значения в языке.Сюда входят варианты использования, которые на первый взгляд могут показаться немного незнакомыми (и не очень полезными), но могут иметь смысл в каком-то сценарии.

Другие советы

Этот:

let print (text : string) = Console.WriteLine text

Создает способ печати как:

print "hi" // prints "hi" in the console

куда:

let print (text : string) () = Console.WriteLine text

производит метод для печати определенной строки, например:

let printHi = print "hi" // Does NOT print a string to the console

printHi () // But now this does print "hi" :)
printHi () // And this...

По сути, это «печать определенной строки X к функции консоли» фабрика, который результат (Ex printhi) может быть повторно использован много раз.

Используя карри,

let makePrinter (text : string) () = Console.WriteLine text

Давайте создадим функцию, которая всегда печатает определенную строку, например,

let helloPrinter = makePrinter "hello"

дает «привет» просто призвать

helloPrinter ()

С другой стороны,

let print (text : string) = Console.WriteLine text

немедленно выводит «текст», если они называются

print "hello"

и возвращает (), а не функция типа unit -> unit Как в первом, Curred Case.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top