Подтвердить что ты не робот

Язык F # - подсказки для новичков

Похоже, здесь в StackOveflow есть группа энтузиастов F #.

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

Спасибо большое

Andrea

4b9b3361

Ответ 1

Не проклинать себя ужасно, но я написал пару обзорных сообщений F # в своем блоге здесь и . Крис Смит (парень в команде F # в MS) имеет статью под названием "F # за 20 минут" - часть 1 и часть 2.

Обратите внимание, что вы должны быть осторожны, поскольку последний CTP F # (версия 1.9.6.0) имеет некоторые серьезные нарушения в сравнении с предыдущими версиями, поэтому некоторые примеры/учебные пособия там могут не работать без изменений.

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

Первое примечание - большинство примеров в Интернете предполагают, что "легкий синтаксис" включен. Для этого используйте следующую строку кода: -

#light

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

Если вы используете интерактивный режим, вам нужно завершить все инструкции с помощью двух полуколонок, например: -

  > #light;;
  > let f x y = x + y;;

  val f : int -> int -> int

  > f 1 2;;
  val it : int = 3

Обратите внимание, что интерактивный режим возвращает результат "val" после каждой строки. Это дает важную информацию о определениях, которые мы делаем, например, "val f: int → int → int" указывает, что функция, которая принимает два ints, возвращает int.

Обратите внимание, что только в интерактивном режиме нам нужно прервать линии с полуколонами, когда на самом деле определяем код F #, мы свободны от этого: -)

Вы определяете функции, используя ключевое слово 'let'. Это, вероятно, самое важное ключевое слово во всех F #, и вы будете использовать его много. Например: -

let sumStuff x y = x + y
let sumStuffTuple (x, y) = x + y

Таким образом, мы можем назвать эти функции: -

sumStuff 1 2
3
sumStuffTuple (1, 2)
3

Обратите внимание, что здесь есть два разных способа определения функций: вы можете либо разделять параметры по пробелам, либо указывать параметры в "кортежах" (т.е. значения в круглых скобках, разделенных запятыми). Разница в том, что мы можем использовать "приложение с частичными функциями" для получения функций, которые принимают меньше требуемых параметров с использованием первого подхода, а не второго. Например: -.

let sumStuff1 = sumStuff 1
sumStuff 2
3

Заметим, что мы получаем функцию из выражения "sumStuff 1". Когда мы можем передавать функции так же легко, как и данные, которые называются языком, имеющим "функции первого класса", это фундаментальная часть любого функционального языка, такого как F #.

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

let someThing x =
  match x with
    | 0 -> "zero"
    | 1 -> "one"
    | 2 -> "two"
    | x when x < 0 -> "negative = " + x.ToString()
    | _ when x%2 = 0 -> "greater than two but even"
    | _ -> "greater than two but odd"

Обратите внимание, что мы используем символ "_", когда хотим что-то сопоставить, но возвращаемое выражение не зависит от ввода.

Мы можем сокращать сопоставление образцов, используя инструкции if, elif и else, если требуется: -

let negEvenOdd x = if x < 0 then "neg" elif x % 2 = 0 then "even" else "odd"

Списки F # (которые реализованы как связанные списки внизу) можно манипулировать таким образом: -

let l1 = [1;2;3]
l1.[0]
1

let l2 = [1 .. 10]
List.length l2
10

let squares = [for i in 1..10 -> i * i]
squares
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]

let square x = x * x;;
let squares2 = List.map square [1..10]
squares2
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]

let evenSquares = List.filter (fun x -> x % 2 = 0) squares
evenSqares
[4; 16; 36; 64; 100]

Обратите внимание: функция List.map "отображает" квадратную функцию в список от 1 до 10, т.е. применяет функцию к каждому элементу. List.filter 'фильтрует' список, возвращая только значения в списке, которые передают предикат. Также обратите внимание на синтаксис "fun x → f" - это F # lambda.

Обратите внимание, что во всех случаях мы не определили какие-либо типы - типы F-компилятора/интерпретатора F #, то есть выработали то, что вы хотите использовать. Например: -

let f x = "hi " + x

Здесь компилятор/интерпретатор определит, что x является строкой, поскольку вы выполняете операцию, для которой x является строкой. Он также определяет, что тип возврата будет также строкой.

Если существует двусмысленность, компилятор делает предположения, например: -

let f x y = x + y

Здесь x и y могут быть несколькими типами, но компилятор по умолчанию имеет значение int. Если вы хотите определить типы, вы можете использовать аннотацию типа: -

let f (x:string) y = x + y

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

Два действительно полезных и сильно используемых оператора в F # - это операторы прямой и функциональной компоновки труб | > и → соответственно.

Определим | > таким образом: -

let (|>) x f = f x

Обратите внимание, что вы можете определить операторы в F #, это довольно круто: -).

Это позволяет вам писать вещи более четко, например: -

[1..10] |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)

Позволит вам получить первые 10 четных квадратов. Это яснее, чем: -

List.filter (fun x -> x % 2 = 0) (List.map (fun x -> x * x) [1..10])

Ну, по крайней мере, я так думаю: -)

Состав функций, определяемый оператором → , определяется следующим образом: -

let (>>) f g x = g(f(x))

т.е. вы пересылаете транзакцию только параметр первой функции остается неуказанным. Это полезно, поскольку вы можете сделать следующее: -

let mapFilter = List.map (fun x -> x * x) >> List.filter (fun x -> x % 2 = 0)

Здесь mapFilter примет список ввода и возвращает список, отфильтрованный, как и раньше. Это сокращенная версия: -

let mapFilter = l |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)

Если мы хотим записать рекурсивные функции, мы должны определить функцию как рекурсивную, поместив "rec" после let. Примеры ниже.

Некоторые интересные вещи: -

Факториал

let rec fact x = if x <= 1 then 1 else x * fact (x-1)

n-й номер Фибоначчи

let rec fib n = if n <= 1 then n else fib (n-1) + fib (n-2)

FizzBuzz

let (/%) x y = x % y = 0
let fb = function
  | x when x /% 15 -> "FizzBuzz"
  | x when x /% 3  -> "Fizz"
  | x when x /% 5  -> "Buzz"
  | x              -> x.ToString()

[1..100] |> List.map (fb >> printfn "%s")

В любом случае, это очень краткий обзор, надеюсь, это поможет немного!

Ответ 2

Без сомнения, вы должны приобрести прекрасную книгу Дона Симэ "Эксперт F #". Книга очень хорошо написана и подходит как для новичков, так и для экспертов. В нем вы найдете как вводный материал, так и гораздо более сложный материал. На почти 600 страницах это хорошее соотношение цены и качества.

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

Книга издана Apress и имеет сопроводительный веб-сайт по адресу: http://www.expert-fsharp.com/default.aspx

Ответ 3

@kronoz - хорошо спасибо за ваш длинный ответ, что действительно хорошее место для начала. Я буду следовать вашим советам и искать упоминаемую книгу @vecstasy.

теперь, позвольте мне перейти к кодированию: -)

let thanksalot = "thanks a lot"
printfn "%s" (thanksalot);;

Ответ 6

Если у вас есть текущая версия CTP в Visual Studio, она позволяет создать проект F # Tutorial, который дает вам Tutorial.fs, точно содержащий то, что он называет.

В этом учебнике также указывается большая коллекция Примеры F # в Microsoft.

Кроме того, в проекте CodePlex.

Надеюсь, что это поможет,

Михиль

Ответ 7

Первая глава моей книги F # для ученых свободно доступна здесь. У нас есть серия бесплатных игрушечных программ F # здесь. Первая статья из нашего журнала F #.NET свободно доступна здесь.