Haskell (МФА: [hæskəl]) — стандартизированный чистый функциональный язык программирования общего назначения. Является одним из самых распространённых языков программирования с поддержкой отложенных вычислений. Система типов — полная, сильная, статическая, с автоматическим выводом типов, основанная на системе типов Хиндли — Милнера. Поскольку язык функциональный, то основная управляющая структура — это функция.

Haskell
Изображение логотипа
Класс языка функциональный, ленивый, модульный
Тип исполнения компилируемый, интерпретируемый
Появился в 1990; 34 года назад (1990)
Автор Аугустссон, Леннарт[вд], Уоррен Бертон[вд], Kevin Hammond[вд], Пол Худак[вд], Джон Хьюз[вд], Томас Юнссон[вд], Саймон Пейтон-Джонс, John Launchbury[вд], Эрик Мейер[вд], Alastair Reid[вд] и Филип Уодлер[вд]
Разработчик Пол Худак[вд][1], Аугустссон, Леннарт[вд][2], Джон Хьюз[вд][3], Саймон Пейтон-Джонс[4], Эрик Мейер[вд][4] и Филип Уодлер[вд][4]
Расширение файлов .hs или .lhs
Выпуск Haskell 2010 (июль 2010; 14 лет назад (2010-07))
Тестовая версия Haskell 2020[5]
Система типов полная сильная статическая с выводом типов
Основные реализации GHC, HUGS, NHC, YHC
Диалекты Helium, Gofer, O'Haskell, Haskell++, Mondrian,
Disciple
Испытал влияние ML и Standard ML, Lazy ML[англ.], Miranda, Lisp и Scheme, ISWIM, FP[англ.],
АПЛ, Hope и Hope+, SISAL[англ.], Orwell, Id[англ.]
Повлиял на Agda, Bluespec[англ.], Clojure, C#, Cat, Cayenne[англ.], Clean, Curry, Epigram[англ.], Escher[англ.], F#, Factor, Idris, Isabelle, Java Generics, LINQ, Mercury, Ωmega[англ.], Python, Qi[англ.], Raku, Rust, Scala, Swift, Timber[англ.], Visual Basic 9.0
Сайт haskell.org
ОС Windows и Unix-подобная операционная система
Логотип Викисклада Медиафайлы на Викискладе

Отличительная черта языка — серьёзное отношение к типизации; во многом в связи с этим язык назван в честь исследователя теории типов и изобретателя комбинаторной логики Хаскелла Карри.

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

История

править

Haskell принадлежит к семейству языков ML. Непосредственно на него оказал большое влияние язык Миранда, разработанный в 1985 году Дэвидом Тёрнером. Миранда был первым чистым функциональным языком, имевшим коммерческую поддержку, и был относительно популярен в 1980-х годах, но оставался собственническим программным обеспечением. Это затрудняло развитие и исследования возможностей ленивого функционального программирования, поэтому буквально за пару лет появилось более десятка схожих языков. Чтобы объединить усилия разных разработчиков в 1987 году на конференции по функциональным языкам программирования и компьютерной архитектуре в Орегоне (FPCA’87) было решено создать комитет для разработки открытого стандарта.

В 1990 году была предложена первая версия языка, Haskell 1.0. В дальнейшем работа комитета продолжилась, и в 1999 году был опубликован «The Haskell 98 Report»[6], который стал стабильным стандартом языка на много лет. Язык, однако, продолжал бурно развиваться, компилятор GHC был фактическим стандартом в отношении новых возможностей.

Разработка новых версий языка идёт открыто, этот процесс получил название Haskell’[7] (Haskell Prime [ˈhæskəl praɪm], «Хаскелл-штрих»). Все желающие могут выдвигать свои предложения к обсуждению, предложения обсуждаются в течение года, комитет отбирает и объявляет предложения, которые готов принять, формируется новый комитет и к концу года готовится новая версия языка. Таким образом, новые версии языка теперь могут появляться каждый год. Планируется объявлять некоторые ревизии «значительными» и поддерживать такие ревизии на протяжении длительного времени.

Версия языка Haskell 2010 — была объявлена в конце 2009 года[8], но последней «значительной» версией (стандартом) остаётся Haskell 98.

Характеристики языка

править

В качестве основных характеристик языка Haskell можно выделить следующие:

С момента принятия последнего стандарта языка (Haskell’98) ведущие реализации языка (ghc и hugs) были расширены множеством дополнительных возможностей:

Реализации языка

править

Есть несколько реализаций языка Haskell[10]. Некоторые реализации ориентированы на практическое применение, в то время как другие — представляют прежде всего академический интерес.

Компиляторы и интерпретаторы

править

Наиболее популярен[11] на практике оптимизирующий компилятор GHC, который создаёт быстрый код и позволяет использовать многие расширения языка. GHC может оптимизировать как скорость, так и компактность программ, способен создавать многозадачный и параллелизованный код. В комплекте с компилятором GHC поставляется также интерактивная среда программирования GHCi со встроенным отладчиком. GHC работает в Windows, MacOS X и на нескольких юникс-подобных платформах (Linux, *BSD, Solaris). Именно GHC является стандартным компилятором в Haskell Platform, и именно на нём в первую очередь тестируются все новые библиотеки[12].

Другая популярная реализация языка — интерпретатор HUGS. Он написан на Си, имеет малый размер дистрибутива и работает практически на всех платформах. HUGS предоставляет интерактивную среду программирования, но может также запускать программы на Haskell в стиле скриптовых языков. Пользователи Windows могут использовать графическую интерактивную среду WinHugs. Поскольку HUGS — это интерпретатор, то программы, запущенные в нём, выполняются медленнее, чем код, созданный большинством компиляторов языка Haskell. HUGS часто рекомендуют в качестве среды для изучения языка. HUGS полностью поддерживает стандарт языка Haskell 98, а также некоторые наиболее популярные расширения языка.

Другие известные реализации[13]:

  • nhc98 — быстрый компилятор, поддерживающий стандарт Haskell 98, написанный на Haskell 98; доступен для всех юникс-подобных платформ, включая MacOS X и Windows/cygwin;
  • YHC (York Haskell Compiler) — форк nhc98, ставящий целью быть более переносимым и эффективным, поддерживает отладчик Hat; генерирует промежуточный байт-код, который можно использовать для генерации кода на других языках программирования;
  • UHC (Utrecht Haskell Compiler) — компилятор, поддерживающий Haskell 98 почти полностью, а также некоторые расширения; поддерживает глобальный анализ программ; имеет несколько кодогенераторов, в том числе почти полностью функциональный генератор JVM-кода, кодогенераторы для LLVM и CLR в состоянии разработки; работает на юникс-подобных системах (включая MacOS X и Windows/cygwin);
  • HBI и HBC — интерпретатор и компилятор, поддерживающие стандарт Haskell 98 с некоторыми расширениями; точно работает в Linux, поддерживается слабо;
  • LHC (The Luxurious LHC Haskell Optimization System) — альтернативный кодогенератор для GHC, поддерживающий глобальную низкоуровневую оптимизацию программы в целом;
  • jhc — экспериментальный компилятор для исследования возможностей глобальной оптимизации программ;
  • Yale Haskell — ранняя реализация языка Haskell на Лиспе.

Haskell Platform

править

В 2009 году сформировалась концепция Haskell Platform[14] — стандартного дистрибутива языка, включающего кроме компилятора (GHC), также дополнительный инструментарий (систему сборки и развёртывания пакетов Cabal) и набор популярных библиотек.

С 2022 года Haskell Platform считается устаревшим способом установки Haskell.

Альтернативные целевые платформы

править

Большинство компиляторов языка Haskell создают непосредственно машинный код для используемой платформы, но есть несколько проектов, позволяющих производить код для виртуальных машин или генерировать код на других языках программирования. Степень зрелости и уровень поддержки подобных проектов сильно разнится.

  • LLVM:
    • патч для GHC[15], добавляющий генератор кода для LLVM, в настоящее время включён в компилятор GHC[16]; использование LLVM позволяет достичь большей производительности на ряде задач[17].
    • альтернативный кодогенератор в UHT (работоспособен частично)
  • виртуальная машина Java (JVM):
    • LambdaVM[18] — патч для GHC, добавляющий генератор байт-кода JVM
    • jvm-bridge[19] — мост между Haskell и JVM (для GHC)
    • jaskell[20] — генератор байт-кода JVM (вероятно заброшен)
    • альтернативный кодогенератор в UHC (работоспособен почти полностью)
  • Common Language Runtime (.Net):
    • прототип генератора MSIL-кода[21] для компилятора EHT/UHT
    • некоторые проекты по поддержке CLR упоминаются в GHC FAQ[22], на начало 2010 года их состояние не ясно
  • JavaScript:
    • кодогенератор JavaScript для GHC[23] — патч для GHC, позволяющий компилировать программы в JavaScript-код
    • Ycr2Js[24] — конвертер байт-кода компилятора YHC в JavaScript
    • Fay — компилятор подмножества Haskell в JavaScript[25]
  • Языки описания архитектуры (Verilog/VHDL):
    • Clash[26] — альтернативный способ разработки ASIC и программирования FPGA

Несколько интересных целевых платформ доступны при использовании компилятора YHC, в частности существуют интерпретатор байт-кода YHC на Python и конвертер байт-кода YHC в Erlang Core, но эти разработки пока ещё экспериментальны. Также существуют реализации подмножеств языка на разных целевых платформах.

Расширения языка

править

Расширения реализаций языка (относится к GHC):

Примеры

править

Вычисление факториала

править

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

 fac :: Integer -> Integer
 fac 0 = 1
 fac n | n > 0 = n * fac (n - 1)

Это определение описывает процесс вычисления факториала в виде рекурсивной функции. Это определение похоже на то, которое можно найти в учебниках по информатике. Большая часть исходного кода на языке Haskell походит на математическую нотацию в аспектах синтаксиса и использования, например, вышеприведённый пример можно переписать в виде

fac n = product [1..n]

что соответствует математическому определению факториала.

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

Вторая и третья строки формируют определение тела функции. Определение состоит из предложений, или «клауз» (англ. clause). Каждое предложение представляет собой пару «образец — выражение». Компилятор или интерпретатор использует механизм сопоставления с образцом для выбора одного из выражений. В данном случае вторая строка определения будет выбрана тогда, когда фактический параметр при вызове функции fac будет равен нулю.

В третьей строке помимо механизма сопоставления с образцами использовано охраняющее выражение — n > 0. Оно гарантирует, что функция не будет работать для отрицательных чисел, для которых факториал не определён. Если отрицательное число будет передано в качестве фактического параметра в функцию fac, то программа остановится с сообщением об ошибке.

Калькулятор

править

Простейший калькулятор для вычисления выражений в обратной польской записи может быть определён на языке Haskell при помощи одной функции:

 calc :: String -> Float
 calc = head . foldl f [] . words
   where 
     f :: [Float] -> String -> [Float]
     f (x:y:zs) "+"    = (y + x):zs
     f (x:y:zs) "-"    = (y - x):zs
     f (x:y:zs) "*"    = (y * x):zs
     f (x:y:zs) "/"    = (y / x):zs
     f (x:y:zs) "FLIP" = y:x:zs
     f (x:zs)   "ABS"  = (abs x):zs
     f xs       y      = read y : xs

Исходная строка со входным выражением тут разбивается стандартной функцией words на список слов — строк между пробельными символами — который обрабатывается функцией левосторонней свёртки (foldl) слева направо по одному слову с помощью функции f, которая поддерживает рабочий список прочитываемых чисел и промежуточных значений (поначалу [] — пустой список) и интерпретирует каждое входное слово как обозначение арифметической функции или как число, в ходе вычисления ею окончательного значения выражения (которое будет первым оставшимся значением в рабочем списке по окончании обработки списка слов входного выражения, так что его можно достать оттуда с помощью стандартной функции head).

Здесь (.) есть оператор композиции функций, (f . g) x = f (g x). Например,

*Main> calc "1 2 3 + 4 * - ABS"
19.0

Числа Фибоначчи

править

Другой пример показывает способ вычисления бесконечного списка чисел Фибоначчи за линейное время:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

Бесконечный список здесь определён при помощи механизма корекурсии — последующие значения списка здесь задаются на основе предыдущих, с начальными 0 и 1 в качестве первых двух элементов списка, и выражением-генератором zipWith (+) fibs (tail fibs), вычисляющим все элементы начиная с третьего на основании предшествующих двух, через стандартную функцию zipWith (+) которая суммирует попарно элементы двух своих входных списков.

Это определение является примером применения механизма ленивых вычислений, который является важнейшей частью языка Haskell. Для понимания того, как это определение работает, можно рассмотреть вычисление первых семи чисел Фибоначчи с его помощью:

fibs         = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ...
               +   +   +   +   +   +
tail fibs    = 1 : 1 : 2 : 3 : 5 : 8 : ...
               =   =   =   =   =   =
zipWith (+)  = 1 : 2 : 3 : 5 : 8 : ...
fibs = 0 : 1 : 1 : 2 : 3 : 5 : 8 : ...

То же самое может быть записано также при использовании определителей списков,

 fibs = 0 : 1 : [a + b | (a,b) <- zip fibs (tail fibs)]

или расширения языка Haskell, реализованного в компиляторе GHC (параллельных определителей списков, англ. parallel list comprehensions):

 fibs = 0 : 1 : [a + b | a <- fibs       
                       | b <- tail fibs]

или с помощью напрямую самореферентной генерирующей функции:

 fibs = 0 : 1 : next fibs
   where
     next (a: t@(b:_)) = (a+b) : next t

Простые числа

править

В этих примерах показано, как можно использовать списочные выражения (генераторы списков). Реализация нахождения всех простых чисел обычным путём (проверка каждого числа на простоту):

 -- общее определение (все натуральные числа > 1, которые являются простыми)
 primeNums = 2 : [n | n <- [3..], isPrime n]
 
 -- Число простое, если у него нет (простых) делителей
 isPrime n = foldr (\p r-> p*p>n || (rem n p /= 0 && r)) True primeNums

или с помощью решета Эратосфена, в прототипичном, неэффективном варианте,

 primes = (map head . scanl minus [2..] . map (\p -> [p, p+p..])) primes

или эффективно, с предварительным каскадным объединением потоков составных чисел:

 primes = 2 : _Y ((3:) . minus [5,7..] . unionAll . map (\p -> [p*p, p*p+2*p..]))
   where 
     _Y g = g (_Y g)
     unionAll ((x:xs):t) = x : union xs (unionAll (pairs t))
     pairs ((x:xs):ys:t) = (x : union xs ys) : pairs t

или посегментно, массивами,

import Data.Array
import Data.List (tails, inits)

ps = 2 : [n | (r:q:_, px) <- (zip . tails . (2:) . map (^2)) ps (inits ps),
              (n,True)    <- assocs (
                                accumArray (\_ _ -> False) True (r+1,q-1)
                     [(m,()) | p <- px, 
                               let s = div (r+p) p * p,  m <- [s,s+p..q-1]] )]

с использованием канонических функций minus, union[27]):

union (x:xs) (y:ys) = case compare x y of
         LT -> x : union  xs (y:ys)
         EQ -> x : union  xs    ys
         GT -> y : union (x:xs) ys
union a b = a ++ b
minus (x:xs) (y:ys) = case compare x y of
         LT -> x : minus  xs (y:ys)
         EQ ->     minus  xs    ys
         GT ->     minus (x:xs) ys
minus a b = a

Описание игральных карт

править

Простой пример использования алгебраических типов данных для описания игральных карт. Идентификаторы типов начинаются с заглавных букв. Идентификаторы переменных и функций — со строчных. Новые алгебраические типы определяются ключевым словом data. Синонимы типов определяются ключевым словом type.

-- Алгебраический тип-сумма Масть («перечисление»).
-- Значением типа Масть может быть одно из указанных справа
-- (или Пики, или Трефы, или Бубны, или Червы).
-- «Масть» здесь выступает конструктором _типа_,
-- а «Пики», «Трефы» и т.д. — конструкторами _данных_.
data Масть = Пики | Трефы | Бубны | Червы
  -- необязательное автоматическое выведение экземпляров классов,
  -- позволяющее преобразовывать значения в строки (функцией show из Show)
  -- и обратно (функцией read из Read), а также сравнивать их между собой
  -- (функциями классов Eq и Ord).
  deriving (Show, Read, Eq, Ord)

-- Алгебраический тип-сумма Достоинство
data Достоинство = Семёрка | Восьмёрка | Девятка | Десятка
                 | Валет | Дама | Король | Туз
  deriving (Show, Read, Eq, Ord)

-- Алгебраический тип-произведение Карта («тип-кортеж»).
-- Значения типа Карта — комбинации значений типов Достоинство и Масть,
-- объединённые конструктором данных К.
-- Часто имена конструктора данных и конструктора типа совпадают.
data Карта = К Достоинство Масть
  deriving (Show, Read, Eq, Ord)

-- Синоним списка значений типа Карта.
type Рука = [Карта]

-- Функция, определяющая, есть ли в руке марьяж (король и дама одной масти).
естьМарьяж :: Рука -> Bool
естьМарьяж карты =
   -- достаточно найти марьяж хотя бы одной масти
   any (естьМарьяжМасти) [Пики, Трефы, Бубны, Червы]
   where
     -- проверить, есть ли и дама, и король заданной масти м в руке
     естьМарьяжМасти м = (К Дама м) `elem` карты && (К Король м) `elem` карты

-- примеры раздач
рука = [ К Дама Трефы, К Семёрка Червы, К Король Трефы, К Туз Бубны ]
рука_без_марьяжа = [ К Десятка Пики, К Король Пики, К Дама Червы ]

main = do
  проверить рука
  проверить рука_без_марьяжа
  проверить [] -- пустая раздача
  where
    проверить кк = putStrLn ( (show кк) ++ " -> " ++ (show (естьМарьяж кк)) )

-- Вывод:
-- [К Дама Трефы,К Семёрка Червы,К Король Трефы,К Туз Бубны] -> True
-- [К Десятка Пики,К Король Пики,К Дама Червы] -> False
-- [] -> False

Численное интегрирование

править

Численное интегрирование   методом трапеций:

trapezeIntegrate f a b n =
    ((sum $ map f [a + h, a + 2*h .. b - h]) + t) * h
    where
        t = (f a + f b)/2
        h = (b - a) / n

main = do
    print $ trapezeIntegrate (\x -> x*sin x) 0 (2*pi) 100

-- Вывод: -6.281118086046067

Проверка палиндромов

править

В примере ниже демонстрируется работа со строками в Юникоде.

import Data.Char (toLower, isAlpha)

palindrom :: [Char] -> Bool
palindrom s =
    norm == reverse norm
    where norm = map toLower $ filter isAlpha $ s

test :: [Char] -> IO ()
test s =
    putStrLn $ s ++ ": " ++ show (palindrom s)

main = do
    test "А в Енисее — синева"
    test "А роза упала на лапу Азора"
    test "Не роза упала на лапу Азора"
    test "Мир как Рим"
    test "Мир не Рим"
    test "I prefer Pi"
    test "حوت فمه مفتوح"
    test "Ne mateno, bone tamen"

-- Вывод:
-- А в Енисее — синева: True
-- А роза упала на лапу Азора: True
-- Не роза упала на лапу Азора: False
-- Мир как Рим: True
-- Мир не Рим: False
-- I prefer Pi: True
-- حوت فمه مفتوح: True
-- Ne mateno, bone tamen: True

Приложения, написанные на языке Haskell

править

Коммерческие приложения

править

Язык получил некоторое распространение в коммерческой среде[28], чему, в частности, способствовала принятая в сообществе традиция выпускать библиотеки под либеральными лицензиями (более 70 % свободно доступных библиотек распространяются на условиях лицензий BSD, MIT или являются общественным достоянием).

Среди коммерческих проектов, реализованных на Haskell — Bluespec SystemVerilog (встраиваемый язык проектирования и верификации полупроводниковых схем, является расширением языка Haskell)[29], Cryptol (коммерческий язык для разработки и проверки криптографических алгоритмов, реализован на Haskell). Первое формально верифицированное микроядро seL4 было тоже написано на Haskell.

Haskell активно применяется в области финансового программирования, анализа рисков, в системах поддержки принятия решений. Haskell применяют разработчики генератора городских ландшафтов для игр и моделирования Gamr7[30]. Есть примеры успешного применения языка для разработки частных информационных систем в коммерческих организациях (в том числе, в странах СНГ)[31]. В аналитической СУБД SQreamDB[англ.] модуль синтаксического разбора SQL написан на Haskell.

Приложения с открытым исходным кодом

править

Значительная часть библиотек и приложений с открытым исходным кодом, написанных на Haskell, доступны в архиве Hackage. Среди них есть универсальный преобразователь различных форматов разметки Pandoc, emacs-подобный текстовый редактор Yi и интегрированная среда разработки Leksah. Среди системных разработок — распределённая система контроля версий Darcs, операционная система House, мозаичный менеджер окон Xmonad.

Компилятор GHC часто выступает экспериментальной площадкой для проверки новых возможностей функционального программирования и оптимизации. При этом на Haskell написаны компиляторы языков Agda, Curry, Epigram[англ.], а также первый компилятор и интерпретатор языка Perl 6 Pugs (был создан всего за месяц).

Примечания

править
  1. 1 2 http://news.yale.edu/2015/04/30/memoriam-paul-hudak-computer-scientist-and-saybrook-college-master
  2. 1 2 http://softwareengineeringdaily.com/2015/11/05/haskell-with-lennart-augustsson/
  3. 1 2 http://www.cse.chalmers.se/~rjmh/Software/h++.html
  4. 1 2 3 4 5 6 A history of Haskell:being lazy with classSIGPLAN, 2007.
  5. "Haskell Prime 2020 committee has formed". Архивировано 11 июня 2016. Дата обращения: 1 апреля 2022.
  6. The Haskell 98 Language Report Архивная копия от 8 марта 2010 на Wayback Machine — получено 05.02.2010
  7. Haskell Prime. Дата обращения: 5 февраля 2010. Архивировано из оригинала 19 декабря 2008 года.
  8. Simon Marlow, Announcing Haskell 2010. Дата обращения: 26 декабря 2009. Архивировано 13 февраля 2015 года.
  9. The Haskell 98 Foreign Function Interface 1.0: An Addendum to the Haskell 98 Report. Дата обращения: 16 октября 2004. Архивировано 10 октября 2004 года.
  10. Реализации языка Haskell (англ.). Дата обращения: 24 февраля 2010. Архивировано 17 марта 2010 года.
  11. "2017 state of Haskell survey results". taylor.fausak.me (англ.). Архивировано 8 ноября 2018. Дата обращения: 12 ноября 2018.
  12. The Glasgow Haskell Compiler. The Architecture of Open Source Applications, Volume 2 Архивная копия от 30 мая 2017 на Wayback Machine, 2012 (англ.)
  13. A history of Haskell: being lazy with class — SIGPLAN, 2007. Дата обращения: 9 сентября 2017. Архивировано 9 сентября 2017 года.
  14. The Haskell Platform. Дата обращения: 24 февраля 2010. Архивировано 27 февраля 2010 года.
  15. Merge Request: LLVM Code Generator for GHC. Дата обращения: 24 февраля 2010. Архивировано из оригинала 23 февраля 2010 года.
  16. The Glasgow Haskell Compiler and LLVM. Дата обращения: 7 августа 2011. Архивировано 25 июня 2011 года.
  17. Smoking fast Haskell code using GHC’s new LLVM codegen. Дата обращения: 24 февраля 2010. Архивировано 25 февраля 2010 года.
  18. LambdaVM. Дата обращения: 24 февраля 2010. Архивировано из оригинала 15 февраля 2010 года.
  19. JVM-Bridge. Дата обращения: 24 февраля 2010. Архивировано из оригинала 8 мая 2010 года.
  20. The Jaskell Project Home Page. Дата обращения: 24 февраля 2010. Архивировано из оригинала 26 января 2009 года.
  21. Running Haskell on the CLR (using UHC). Дата обращения: 24 февраля 2010. Архивировано 9 августа 2021 года.
  22. 1.5.1 Why isn’t GHC available for .NET or on the JVM? Дата обращения: 24 февраля 2010. Архивировано 29 марта 2010 года.
  23. кодогенератор JavaScript для GHC. Дата обращения: 24 февраля 2010. Архивировано из оригинала 13 марта 2010 года.
  24. Yhc/Javascript, YCR2JS, a Converter of Yhc Core to Javascript. Дата обращения: 24 февраля 2010. Архивировано 3 июня 2010 года.
  25. Home · faylang/fay Wiki · GitHub. Дата обращения: 25 июня 2013. Архивировано 24 июня 2013 года.
  26. CλaSH — From Haskell to Hardware. Дата обращения: 16 июня 2018. Архивировано 15 июня 2018 года.
  27. Функции из модуля Data.List.Ordered Архивная копия от 1 октября 2011 на Wayback Machine
  28.  (англ.)Коммерческие применения языка Haskell Архивная копия от 8 апреля 2017 на Wayback Machine
  29. Bluespec. Дата обращения: 6 февраля 2010. Архивировано 6 февраля 2010 года.
  30. Gamr7: UrbanPAD. The Software for 3D city & buildings creation. Дата обращения: 18 февраля 2010. Архивировано 16 февраля 2010 года.
  31. Астапов Дмитрий. Использование Haskell при поддержке критически важной для бизнеса информационной системы // Практика функционального программирования : Журнал. — 2009. — № 2. — С. 53—69. Архивировано 13 февраля 2010 года.

Литература

править
  • Bryan O’Sullivan, John Goerzen, Don Stewart. Real World Haskell — O’Reilly, 2008—710 °C. ISBN 0-596-51498-0. ISBN 978-0-596-51498-3
  • Душкин Роман Викторович. Функциональное программирование на языке Haskell / Гл. ред. Д. А. Мовчан;. — М.: ДМК Пресс,, 2008. — 544 с., ил. с. — 1500 экз. — ISBN 5-94074-335-8.

Ссылки

править
  • haskell.org — основной сайт, посвящённый языку Haskell; содержит различные справочные материалы, список интерпретаторов и компиляторов Haskell (в настоящий момент, все интерпретаторы и компиляторы бесплатны). Кроме того, имеется обширный список ссылок на ресурсы по теории функционального программирования и другим языкам (Standard ML, Clean).

Учебный и справочный материал