Обзор реализации основных возможностей функционального языка программирования в среде PascalABC.NET: различия между версиями
Материал из Вики проекта PascalABC.NET
Перейти к навигацииПерейти к поиску
(Новая: ==Реализовано с помощью узлов синтаксического дерева PascalABC :== * Подключение внешних сборок (import) * Типы ...) |
Tasha (обсуждение | вклад) |
||
(не показано 12 промежуточных версий 3 участников) | |||
Строка 1: | Строка 1: | ||
==Реализовано с помощью узлов синтаксического дерева PascalABC :== | ==Реализовано с помощью узлов синтаксического дерева PascalABC :== | ||
* Подключение внешних сборок (import) | * Подключение внешних сборок (import) | ||
* Модули | |||
* Типы данных : булевский, вещественный, целый, символьный и строки | * Типы данных : булевский, вещественный, целый, символьный и строки | ||
* Простые операции с ними | * Простые операции с ними | ||
Строка 7: | Строка 8: | ||
* if, case, охранные выражения | * if, case, охранные выражения | ||
* Операторы do, print, return | * Операторы do, print, return | ||
* Локальные переменные (where) | * Локальные переменные (where, let) | ||
* Списки (перечислимые, прогрессии, бесконечные) | * Списки (перечислимые, прогрессии, бесконечные), списки списков | ||
* Конструкторы списков | |||
* Кортежи | |||
* Оператор ‘:’ | * Оператор ‘:’ | ||
* Частично обработка ошибок | * Частично обработка ошибок | ||
* Комментарии --, | * Комментарии --, {-, -} | ||
* Лямбда-функция(новый узел) | |||
* Каррирование | |||
* Функции высшего порядка | |||
* Неопределенный параметр функции_ | |||
* Инфиксные функции | |||
* Тригонометрические функции | |||
==Обзор== | ==Обзор== | ||
<ol> | <ol> | ||
<li TYPE=I> | <li TYPE=I> | ||
Математическим фундаментом функционального программирования является лямбда-исчисление. Такие языки как Haskell и Clean имеют 100% соответствие своей семантики с семантикой подразумеваемых конструкций лямбда-исчисления. Используя лямбда-абстракции можно определить булевские значения и условия, пары и кортежи и даже натуральные числа. | Математическим фундаментом функционального программирования является '''лямбда-исчисление'''. Такие языки как Haskell и Clean имеют 100% соответствие своей семантики с семантикой подразумеваемых конструкций лямбда-исчисления. Используя лямбда-абстракции можно определить булевские значения и условия, пары и кортежи и даже натуральные числа.<br> | ||
Натуральные числа и булевские выражения и операции с ними проще определить, используя их определение в PascalABC. Прямую рекурсию также легче реализовать естественным путем. Для других конструкций целесообразно использовать лямбда-функции: | |||
<ol> | |||
<li> безымянные функции | |||
<li> именованные выражения | |||
<ol> | |||
<li TYPE=a> let x=s in T ↔ (λx.T) s | |||
<li TYPE=a> T where x=s ↔ (λx.T) s | |||
</ol> | |||
<li> определение правой части функции через лямбда-выражение, т.е. реализовать if, case и сравнение с образцом → благодаря этому будет возможно описание функции, используя if и case, внутри выражения | |||
<li> реализация функций высшего порядка и каррирования. | |||
</ol> | |||
Для реализации лямбда-исчисления может быть использована библиотека в .NET Framework 4 Beta1 Expression.Lambda. | |||
private static Func<object, object> CreateGetter(object entity, string propertyName) | |||
{ | |||
var param = Expression.Parameter(typeof (object), «e»); | |||
Expression body = Expression.PropertyOrField(Expression.TypeAs(param, entity.GetType()), propertyName); | |||
var getterExpression = Expression.Lambda<Func<object, object>>(body, param); | |||
return getterExpression.Compile(); | |||
} | |||
<li TYPE=I> | |||
'''Выводимость типов.''' Тип функции выводится интерпретатором в зависимости от того, от каких аргументов она вызывается. | |||
<li TYPE=I> | |||
'''Реализация ленивых вычислений.''' Функциональные языки делятся на 2 лагеря: те, в которых параметры передаются по значению, и те, в которых имеет место вызов по необходимости (вычисление производится один раз). Ленивые вычисления можно реализовать, сделав специальную обертку для параметров. В Framework 4 есть такая поддержка ленивых вычислений – класс Lazy.</li> | |||
static void F(Lazy<int> a) | |||
{ | |||
Console.WriteLine(a.value);// a вычислится только здесь при вызове | |||
} | |||
<li TYPE=I> | |||
'''Классы типов.''' Класс типов представляет собой некоторое множество типов языка, обладающих общими свойствами. Классы позволяют определять, какие типы являются экземплярами каких классов, и предоставлять определения ассоциированных с классом операций, перегруженных для каждого типа. Интуитивно классы типов можно понимать как интерфейсы. | |||
<li TYPE=I> | |||
'''Монады и определение типов data, операция ←.''' В Haskell монады нужны в первую очередь для определения операций ввода-вывода, т.к. они не соответствуют парадигмам функционального программирования (getChar вызывается от одного и того же аргумента, а результат разный). | |||
</ol> | </ol> | ||
==Ссылки== | |||
* http://kchri.narod.ru | |||
* http://ru.wikipedia.org/wiki/Язык_функционального_программирования | |||
* http://learnyouahaskell.com/chapters |
Текущая версия от 12:26, 17 апреля 2010
Реализовано с помощью узлов синтаксического дерева PascalABC :
- Подключение внешних сборок (import)
- Модули
- Типы данных : булевский, вещественный, целый, символьный и строки
- Простые операции с ними
- Описание функций и главная функция main
- Сопоставление с образцом
- if, case, охранные выражения
- Операторы do, print, return
- Локальные переменные (where, let)
- Списки (перечислимые, прогрессии, бесконечные), списки списков
- Конструкторы списков
- Кортежи
- Оператор ‘:’
- Частично обработка ошибок
- Комментарии --, {-, -}
- Лямбда-функция(новый узел)
- Каррирование
- Функции высшего порядка
- Неопределенный параметр функции_
- Инфиксные функции
- Тригонометрические функции
Обзор
-
Математическим фундаментом функционального программирования является лямбда-исчисление. Такие языки как Haskell и Clean имеют 100% соответствие своей семантики с семантикой подразумеваемых конструкций лямбда-исчисления. Используя лямбда-абстракции можно определить булевские значения и условия, пары и кортежи и даже натуральные числа.
Натуральные числа и булевские выражения и операции с ними проще определить, используя их определение в PascalABC. Прямую рекурсию также легче реализовать естественным путем. Для других конструкций целесообразно использовать лямбда-функции:- безымянные функции
- именованные выражения
- let x=s in T ↔ (λx.T) s
- T where x=s ↔ (λx.T) s
- определение правой части функции через лямбда-выражение, т.е. реализовать if, case и сравнение с образцом → благодаря этому будет возможно описание функции, используя if и case, внутри выражения
- реализация функций высшего порядка и каррирования.
Для реализации лямбда-исчисления может быть использована библиотека в .NET Framework 4 Beta1 Expression.Lambda.
private static Func<object, object> CreateGetter(object entity, string propertyName) { var param = Expression.Parameter(typeof (object), «e»); Expression body = Expression.PropertyOrField(Expression.TypeAs(param, entity.GetType()), propertyName); var getterExpression = Expression.Lambda<Func<object, object>>(body, param); return getterExpression.Compile(); }
- Выводимость типов. Тип функции выводится интерпретатором в зависимости от того, от каких аргументов она вызывается.
- Реализация ленивых вычислений. Функциональные языки делятся на 2 лагеря: те, в которых параметры передаются по значению, и те, в которых имеет место вызов по необходимости (вычисление производится один раз). Ленивые вычисления можно реализовать, сделав специальную обертку для параметров. В Framework 4 есть такая поддержка ленивых вычислений – класс Lazy. static void F(Lazy<int> a) { Console.WriteLine(a.value);// a вычислится только здесь при вызове }
- Классы типов. Класс типов представляет собой некоторое множество типов языка, обладающих общими свойствами. Классы позволяют определять, какие типы являются экземплярами каких классов, и предоставлять определения ассоциированных с классом операций, перегруженных для каждого типа. Интуитивно классы типов можно понимать как интерфейсы.
- Монады и определение типов data, операция ←. В Haskell монады нужны в первую очередь для определения операций ввода-вывода, т.к. они не соответствуют парадигмам функционального программирования (getChar вызывается от одного и того же аргумента, а результат разный).