Совсем
недавно мне довелось познакомиться с таким уникальным языком разработки, как F#. Его гибкость и возможности поразили меня. Признаюсь, знакомство с F# началось у меня около года назад, но тогда этот
язык просто не "зацепил" меня. Наконец я попробовал снова сосредоточить на нем внимание, изменив при этом свой
подход к изучению. Основная проблема, которая иногда у меня проявляется при знакомстве с новым языком, кроется в попытке проецировать
возможности известного языка разработки на изучаемый. Следует рассматривать язык как уникальную единицу, призванную решать свои задачи, и если пробовать нагружать
на него специфику известного языка, станут заметны несоответствия и может сложиться мнение, что
изучаемый язык "недоразвит". Проблема кроется зачастую не в языке, а
в нас: мы зачастую пытаемся проецировать то, что есть в нашей памяти, на все новое, пытаясь найти аналогии, и это
касается не только разработки. Такое поведение можно наблюдать, например, при изучении иностранных языков.
Отойдем от рассуждений и попробуем беспристрастно взглянуть на этот язык. Мне понравилась книга "Chad Fowler, The Passionate Programmer", советы из которой стараюсь применять каждый день, чтобы повышать свой уровень. Один из таких советов звучит: "Чтобы понять, действительно ли Вы знаете что-либо, попробуйте обучить этому кого-то еще". Нет лучшего способа закрепить свои знания, чем заставить себя ясно сформулировать их кому-то еще. Обычное формулирование чего-либо является популярным средством для "очищения" разума. Общение с куклами или другими неодушевленными предметами как способ решения проблем является довольно известным элементом программистского фольклора (источник). Поэтому давайте попробуем учиться вместе. Надеюсь, что данный язык Вам понравится своими возможностями и мои старания не прошли даром. Для начала создадим новое приложение, как показано на рисунке ниже.
Отойдем от рассуждений и попробуем беспристрастно взглянуть на этот язык. Мне понравилась книга "Chad Fowler, The Passionate Programmer", советы из которой стараюсь применять каждый день, чтобы повышать свой уровень. Один из таких советов звучит: "Чтобы понять, действительно ли Вы знаете что-либо, попробуйте обучить этому кого-то еще". Нет лучшего способа закрепить свои знания, чем заставить себя ясно сформулировать их кому-то еще. Обычное формулирование чего-либо является популярным средством для "очищения" разума. Общение с куклами или другими неодушевленными предметами как способ решения проблем является довольно известным элементом программистского фольклора (источник). Поэтому давайте попробуем учиться вместе. Надеюсь, что данный язык Вам понравится своими возможностями и мои старания не прошли даром. Для начала создадим новое приложение, как показано на рисунке ниже.
После
этого увидим код:
[<EntryPoint>]
let main
argv =
printfn "%A" argv
0 //
return an integer exit code
Это
пример обычного консольного приложения, в котором [<EntryPoint>] – это точка входа в программу.
let main argv =
Указываем, что функция main является точкой в программу, argv – это аргументы этой функции. Как можно увидеть в Intellicence, функция
возвращает int.
Функция
printfn
аналогична функциям из языка C
и
Python,
только в C#
она называется иначе. Например, ту же логику, какую делает эта функция, можно
проделать на C#
функцией string.Format или
для консольного приложения передать необходимые параметры в функцию Console.WriteLine.
Попробуем
написать простенькую функцию, которая будет суммировать два числа, и одну
функцию, которая будет воспроизводить число в квадрате.
open System
let square
x = x * x
let add x y
=
x + y
[<EntryPoint>]
let main
argv =
let z = 5
printfn "Test square function %i" (square 5)
printfn "An int: %i" z
printf "Test add function %i" (add 5 7)
Console.ReadLine() |> ignore
0 //
return an integer exit code
Для
паузы в программе я использовал функцию Console.ReadLine(), но поскольку мне не важен результат, который
возвращает данная функция, я указал для данной функции игнорировать результат
возвращаемого значения.
Console.ReadLine() |> ignore
Открываем пространство имен System для F# с помощью кода
open System
Теперь поближе остановимся на самих функциях
let square
x = x * x
Функция square принимает на вход один параметр. Посмотрите на рисунок ниже, чтобы понять,
как работают функции в F#.
Соответственно, функция add принимает на вход два аргумента – x, y – и возвращает сумму этих аргументов. Если мы переносим результат выполнения
функции на новую строку, то у нас должен быть с левой стороны как минимум один
пробел, так как F# не будет понимать, что Вы создали функцию.
Рассмотрим, как нам можно создать кастомный тип данных.
type Person
= { Name: string; Age: int}
let mass =
[|
{Name = "Test"; Age = 32};
{Name = "Test2"; Age = 25}
|]
Выше мы создали тип данных Person, который имеет два члена Name и Age. А ниже – двумерный массив нашего
типа Person. К сожалению, типы данных в C# являются
неизменяемыми, поэтому мы не можем написать код на подобии такого для изменения
некоего значения данного поля.
let person
= {Name = "Test"; Age = 32}
person.Name <- "1234567890"
Но
мы легко можем создать новый тип Person, в котором обновить
нужное значение.
let person
= {Name = "Test"; Age = 32}
let partDeux = { person with Name = "Expert F# 2.0" }
Давайте
попрактикуемся в создании функций в отдельных модулях. Для этого
выберем в Visual Studio создание нового
файла, как показано на рисунке ниже.
Затем
перенесем наши функции в этот файл.
module
Calculation
let square
x = x * x
let add x y
=
x + y
После этого нужно немного модифицировать код, чтобы можно
использовать эти функции.
open System
[<EntryPoint>]
let main
argv =
let z = 5
printfn "Test square function %i" (Calculation.square 5)
printfn "An int: %i" z
printf "Test add function %i" (Calculation.add 5 7)
Console.ReadLine() |> ignore
0 //
return an integer exit code
Но
как Вы увидите, Intellicence будет подчеркивать
данный код как ошибку. Все дело в том, что порядок следования файлов в языке F# имеет значение. Нам достаточно выделить добавленный
нами файл и нажать Move Up, как показано на
рисунке ниже.
Вам
необходимо переместить добавленный файл Calculation.fs, чтобы он оказался
перед файлом Program.fs. После
запуска мы можем запустить приложение и увидеть, что оно работает.
Что же делать, если нам нужно несколько модулей, как разделить их, ведь в одном
файле они работать не будут. Для этого в F# существует разделение по пространствам имен namespace. Добавим еще один модуль в файл Calculation.fs и назовем его Multiply. Затем те два модуля, которые у нас получились, добавим
в пространство имен CalculationOperation.Code. Пример приведен ниже.
namespace
CalculationOperation.Code
module
Calculation =
let square
x = x * x
let add x y
=
x + y
module
Multiply =
let div x y
= x / y
Теперь
посмотрим, как использовать то, что мы написали. J
open System
open
CalculationOperation.Code
[<EntryPoint>]
let main
argv =
let z = 5
printfn "Test square function %i" (Calculation.square 5)
printfn "An int: %i" z
printf "Test add function %i" (Calculation.add 5 7)
printf "Test div function %i" (Multiply.div 4 2)
Console.ReadLine() |> ignore
0 //
return an integer exit code
Итоги
В приведенной статье мы рассмотрели простенькие примеры использования возможностей языка F#. Надеюсь, что примеры были несложные и это не отпугнет Вас от дальнейшего изучения данного языка. В следующей статье попробуем создать на F# приложение Windows Forms и WPF. Для первого раза, думаю, будет достаточно, чтобы не отбить у читателей охоту изучать F# в дальнейшем.
No comments:
Post a Comment