2008-09-19 2 views
23

Я пытался зайти в F # на некоторое время, но я все время откладываю. Зачем?Что значит -> означает в F #?

Потому что независимо от того, какой ресурс «новичков» я пытаюсь посмотреть, я вижу очень простые примеры, которые начинают использовать оператор ->.

Однако я нигде не нашел, что дает ясное простое объяснение того, что означает этот оператор. Это похоже на то, что это должно быть настолько очевидно, что оно не нуждается в объяснении даже для завершения новичков.

Поэтому я должен быть очень плотным или, возможно, это почти три десятилетия предыдущего опыта, удерживающего меня.

Может кто-нибудь, пожалуйста, объясните это или укажите действительно доступный ресурс, который объясняет это?

+0

Все это действительно кажется мне греческим. – Brettski 2008-09-19 19:24:33

+0

Просто назовите его Мафусалой. – 2008-09-19 19:40:16

+0

На самом деле Мафусаил жил в течение 969 лет, поэтому я все равно остался бы на треть от его возраста. Тем не менее, отредактировано спасибо;) – AnthonyWJones 2008-09-20 20:01:22

ответ

46

'->' не является оператором. Он появляется в синтаксисе F # в ряде мест, и его смысл зависит от того, как он используется как часть более крупной конструкции.

Внутри типа '->' описывает типы функций, как описано выше. Например,

let f : int -> int = ... 

говорит, что 'f' - это функция, которая принимает int и возвращает int.

Внутри лямбда («вещь, которая начинается с« веселого »ключевого слова»), '->' - это синтаксис, который отделяет аргументы от тела. Например,

fun x y -> x + y + 1 

- это выражение, которое определяет две функции аргумента с данной реализацией.

Внутри конструкции «match», '->' является синтаксисом, который отделяет шаблоны от кода, который должен выполняться, если шаблон сопоставляется. Например, в

match someList with 
| [] -> 0 
| h::t -> 1 

материала слева от каждого «->» являются узорами, и материал по праву является то, что происходит, если рисунок на левом был подобран.

Сложность понимания может быть связана с ошибочным предположением, что '->' является «оператором» с одним значением. Аналогия может быть «.» в C#, если вы никогда не видели какой-либо код раньше, и попытайтесь проанализировать «.». оператор, основанный на взгляде на «obj.Method» и «3.14» и «System.Collections», вы можете сильно запутаться, потому что символ имеет разные значения в разных контекстах. Однако, когда вы знаете достаточно языка для распознавания этих контекстов, все становится ясным.

12

В основном это означает «карты». Прочтите это так или как «трансформируется» или что-то в этом роде.

Так, из F# in 20 minutes учебника,

> List.map (fun x -> x % 2 = 0) [1 .. 10];; 
val it : bool list 
= [false; true; false; true; false; true; false; true; false; true] 

Код (удовольствие я -> я% 2 = 0) определяет анонимную функцию, которая называется выражение лямбда , который имеет параметр х и функция возвращает результат «x % 2 = 0», что равно или равно x равно .

1

От Microsoft:

типы функций являются типы, данные значений функции первого класса и написаны Int -> Int. Они аналогичны для типов делегатов .NET, за исключением того, что им не присвоены имена . Все функции F # могут использоваться в качестве значений функции первого класса, а значения анонимных значений могут быть созданы с использованием формы выражения (fun ... -> ...).

4

(a -> b) означает «функция от a до b». В аннотации типа он обозначает тип функции. Например, f: (int -> String) означает, что f относится к функции, которая принимает целое число и возвращает строку. Он также используется в качестве contstructor таких значений, как в

val f : (int -> int) = fun n -> n * 2 

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

0

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

adder n x y = n + x + y 

другими словами: «дайте мне три вещи, и я добавлю их вместе». Когда вы бросаете в него числа, компилятор выводит типы n x и y.Скажем, вы пишете

adder 1 2 3 

Тип 1, 2 и 3 - Int. Поэтому:

adder :: Int -> Int -> Int -> Int 

То есть, дайте мне три целых числа, и я стану целым числом, в конце концов, или то же самое, как говорят:

five :: Int 
five = 5 

Но вот хорошая часть! Попробуйте это:

add5 = adder 5 

Как вы помните, гадюка принимает INT, в INT, в INT, и дает вам обратно в Int. Однако это не вся правда, как вы вскоре увидите. На самом деле, add5 будет иметь этот тип:

add5 :: Int -> Int -> Int 

Это будет, как если бы вы «отслаивается» из целых чисел (самый левый), и приклеить его непосредственно к функции. Приглядевшись в подписи функции, мы замечаем, что -> являются правоассоциативной, то есть:

addder :: Int -> (Int -> (Int -> Int)) 

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

add5andtwomore :: Int -> (Int -> Int) 
add5andtwomore = adder 5 

Теперь вы можете использовать add5andtwomore вместо «сумматора 5». Таким образом, вы можете использовать другое число, чтобы получить (например) «add5and7andonemore»:

add5and7andonemore :: Int -> Int 
add5and7andonemore = adder 5 7 

Как вы видите, add5and7andonemore хочет точно еще один аргумент, и, когда вы даете ему, то он внезапно стал целым!

> add5and7andonemore 9 
=> ((add5andtwomore) 7) 9 
=> ((adder 5) 7) 9) 
<=> adder 5 7 9 

Подставляя параметры в сумматоре (NXY) для (5 7 9), получим:

> adder 5 7 9 = 5 + 7 + 9 
=> 5 + 7 + 9 
=> 21 

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

> 5 + 7 + 9 
=> (+ 5 (+ 7 9)) 
=> (+ 5 16) 
=> 21 

Там вы идете!

1

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

'->' означает функцию.

«а ->» Ь это функция, которая принимает «а и возвращает„B

(“а *„б) -> (“с *» г) представляет собой функцию, которая принимает кортеж типа ('a,' b) и возвращает кортеж ('c,' d). Например, int/string возвращает float/char.

Где интересно, в каскадном случае 'a ->' b -> 'c. Это функция, которая принимает 'a и возвращает функцию (' b -> 'c), или функцию, которая берет' b -> 'c.

Так что, если вы пишете: пусть fxyz =()

Тип будет F: 'а ->' Ь -> «с -> блок, так что если вы только применили первый параметр, результат будет представлять собой валютную функцию 'b ->' c -> '.

1

В контексте определения функции он аналогичен => из выражения лямбда в C# 3.0.

F#: let f = fun x -> x*x 
C#: Func<int, int> f = x => x * x; 

-> в F # также используется в сопоставлении с образцом, где это означает: если выражение соответствует части между | и ->, то, что происходит после того, как -> должно быть возвращено в результате:

let isOne x = match x with 
| 1 -> true 
| _ -> false 
9

Первый вопрос - вы знакомы с лямбда-выражениями на C#? Если так, то -> в F # совпадает с => в C# (я думаю, вы читаете «идет»).

The -> Оператор также может быть найден в контексте соответствия шаблона

match x with 
| 1 -> dosomething 
| _ -> dosomethingelse 

Я не уверен, если это также лямбда-выражение, или что-то еще, но я предполагаю, что «идет к» сохраняется.

Может быть то, что вы на самом деле в виду, является F # парсера «загадочные» ответы:

> let add a b = a + b 
val add: int -> int -> int 

Это означает (как большинство примеров объяснить), добавляющие является «вал», который принимает два целых и возвращает int. Для меня это было совершенно непрозрачно для начала. Я имею в виду, откуда я знаю, что add - это не val, который принимает один int и возвращает два ints?

Ну, дело в том, что в некотором смысле это так. Если я дам добавить только один Int, я вернусь к (Int -> Int):

> let inc = add 1 
val inc: int -> int 

Это (выделка) является одной из вещей, которая делает F # так сексуально для меня.

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

1

Много замечательных ответов на эти вопросы, спасибо людям. Я хотел бы привести здесь редактируемый ответ, который объединяет вещи.

Для тех, кто знаком с пониманием C# -> тем же, что и => выражение lamba - хороший первый шаг. Это использование: -

fun x y -> x + y + 1 

Может быть понято как эквивалентном: -

(x, y) => x + y + 1; 

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

Поэтому, когда выше описано, как это: -

Int -> Int -> Int 

Это действительно помогло бы знать, что -> является правильным ассоциативным, следовательно, выше можно считать: -

Int -> (Int -> Int) 

Aha! У нас есть функция, которая принимает Int и возвращает (Int -> Int) (карри-функция?).

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

Также полезен -> появляется в другом синтаксисе, таком как совпадение, но там он не имеет того же значения? Это верно? Я не уверен, что это так. Я подозреваю, что он имеет то же значение, но у меня нет словарного запаса, чтобы это выразить.

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

Смежные вопросы