Haskell ( / ˈ h æ s k əl / [ 25 ] ) は、型推論と遅延評価を備えた、汎用的で静的型付けの純粋関数型プログラミング言語です。[ 26 ] [ 27 ] Haskell は、型安全な演算子オーバーロードのための型クラスやモナド入出力(IO)など、いくつかのプログラミング言語機能を先駆けて導入しました。論理学者のHaskell Curryにちなんで名付けられました。[ 1 ] Haskell の主な実装は、グラスゴー Haskell コンパイラ(GHC) です。
Haskellのセマンティクスは、歴史的にMirandaプログラミング言語のセマンティクスに基づいており、初期のHaskellワーキンググループの取り組みを集中させるのに役立ちました。[ 28 ]この言語の最後の正式な仕様は2010年7月に作成されましたが、GHCの開発は言語拡張を通じてHaskellを拡張し続けています。
Haskellは学術界と産業界で利用されている。[ 29 ] [ 30 ] [ 31 ] 2021年5月現在 Haskellは、チュートリアルに関するGoogle検索では28番目に人気のあるプログラミング言語であり[ 32 ] 、 GitHubソースコードリポジトリ のアクティブユーザーの1%未満を占めていました[ 33 ] 。
1985年にResearch Software Ltd.がMirandaをリリースした後、遅延評価関数型言語への関心が高まった。1987年までに、12種類以上の非厳密な純粋関数型プログラミング言語が存在した。Mirandaは最も広く使われていたが、プロプライエタリソフトウェアだった。オレゴン州ポートランドで開催された関数型プログラミング言語とコンピュータアーキテクチャに関する会議(FPCA '87)では、そのような言語のオープンスタンダードを定義するための委員会を設立すべきだという強い合意が得られた。委員会の目的は、既存の関数型言語を共通のものに統合し、関数型言語設計の将来の研究の基礎とすることだった。[ 34 ]
Haskellは委員会によって開発され、可能な限り既製のソリューションを統合しようと試みられた。
型クラスは、当時言語における等価型と算術オーバーロードの場当たり的な処理に対処するために、フィリップ・ワドラーとスティーブン・ブロットによって最初に提案されました。 [ 35 ]
Haskellの初期バージョン(バージョン1.2まで)では、ユーザーとのやり取りと入出力(IO)は、ストリームベースと継続ベースの両方のメカニズムで処理されていましたが、これらは広く不十分だと考えられていました。[ 36 ]バージョン1.3では、モナドIOが導入され、型クラスが高次の型(型コンストラクタ)に一般化されました。型クラスの構文糖衣を提供する「do記法」と合わせて、MonadこれによりHaskellは参照透過性を維持し、便利な効果システムを手に入れました。
初期バージョンにおけるもう1つの注目すべき変更点は、「逐次評価」操作seq(値間のデータ依存関係を作成し、遅延評価言語で過剰なメモリ消費を回避するために使用される)を型クラスから標準関数に移動して、リファクタリングをより実用的にしたことです。
Haskellの最初のバージョン(「Haskell 1.0」)は1990年に定義されました。[ 1 ]委員会の努力の結果、一連の言語定義(1.0、1.1、1.2、1.3、および1.4)が作成されました。

FoldableTraversableApplicativeFunctorMonad1997年後半、このシリーズはHaskell 98で最高潮に達しました。これは、安定した最小限の移植可能なバージョンの言語と、教育用の標準ライブラリ、そして将来の拡張の基盤となることを意図したものでした。委員会は、実験的な機能を追加および組み込むことによってHaskell 98の拡張とバリアントを作成することを明確に歓迎しました。[ 34 ]
1999年2月、Haskell 98言語標準が「The Haskell 98 Report」として初めて公開されました。[ 34 ] 2003年1月には、改訂版が「Haskell 98 Language and Libraries: The Revised Report」として公開されました。[ 27 ]この言語は急速に進化を続けており、Glasgow Haskell Compiler (GHC) の実装が現在の事実上の標準となっています。[ 37 ]
2006 年初頭、Haskell 98 標準の後継となる標準を定義するプロセスが開始されました。これは非公式にはHaskell Primeと呼ばれていました。 [ 38 ]これは、言語定義を改訂するための継続的な漸進的プロセスであり、年に 1 回まで新しい改訂版を作成する予定でした。最初の改訂版であるHaskell 2010は、2009 年 11 月に発表され[ 2 ]、2010 年 7 月に公開されました。
Haskell 2010では、これまでコンパイラ固有のフラグによって有効化されていた、広く利用され、議論の余地のない機能がいくつか追加されました。
Data.ListではなくList)。ただし、技術的にはモジュールは依然として単一のモノリシックな名前空間に属しています。この拡張機能はHaskell 98の補遺で規定され、実際には広く使用されていました。fact (n+1) = (n+1) * fact n) はもはや許可されませんでした。この構文糖衣は誤解を招く意味論を持っており、コードは(+)演算子を使用しているように見えますが、実際には と を使用したコードに脱糖されていまし(-)た(>=)。LANGUAGEプラグマは既に規定されていました。2010年までに、数十もの言語拡張機能が広く使われるようになり、GHC(およびその他のコンパイラ)は、LANGUAGE識別子のリストを用いて個々の拡張機能を指定するためのプラグマを提供しました。Haskell 2010コンパイラは、このHaskell2010拡張機能をサポートすることが義務付けられており、Haskell 2010で追加された拡張機能に対応する他のいくつかの拡張機能もサポートすることが推奨されています。次の正式な仕様は2020年に予定されていました。[ 3 ] 2021年10月29日、GHCバージョン9.2.1でGHC2021拡張機能がリリースされました。これは正式な言語仕様ではありませんが、Haskell 2010にいくつかの安定した広く使用されているGHC拡張機能を組み合わせたものです。[ 39 ] [ 40 ]
Haskellは、遅延評価、ラムダ式、パターンマッチング、リスト内包表記、型クラス、型多相性といった機能を備えています。純粋関数型プログラミング言語であり、関数は一般的に副作用を持ちません。副作用を表すための独自の構造が存在し、これは関数の型とは直交しています。純粋関数は、他の言語の不純関数をモデル化するように、後続で実行される副作用を返すことができます。
Haskell は、 Hindley–Milner 型推論に基づく強力な静的型システムを備えています。この分野における Haskell の主な革新は型クラスであり、元々は言語にオーバーロードを追加するための原理的な方法として考案されましたが、 [ 41 ]その後、さらに多くの用途が見出されました。[ 42 ]
副作用を表す構成要素はモナドの一例です。モナドとは、エラー処理、非決定性、構文解析、ソフトウェアのトランザクションメモリなど、さまざまな計算をモデル化できる汎用的なフレームワークです。これらは通常のデータ型として定義されますが、Haskellではそれらを使用するための構文糖衣が提供されています。
Haskellには公開された仕様があり、[ 27 ]複数の実装が存在します。その主要な実装であるグラスゴーHaskellコンパイラ(GHC)は、ほとんどのプラットフォームで動作するインタプリタとネイティブコードコンパイラの両方です。GHCは、一般化代数データ型や型ファミリーなどの最近のイノベーションを取り入れた豊富な型システムで知られています。Computer Language Benchmarks Gameでは、並行処理と並列処理の高性能な実装も強調されています。[ 43 ]
この言語には活発で成長を続けるコミュニティが存在し、オンラインパッケージリポジトリHackageには5,400以上のサードパーティのオープンソースライブラリとツールが利用可能です。[ 44 ]
Haskellで書かれた「Hello, World!」プログラム(最後の行のみ必須):
module Main ( main ) where -- インタプリタでは不要、モジュールファイルではデフォルトですmain :: IO () -- コンパイラはこの型定義を推論できますmain = putStrLn "Hello, World!"Haskellにおける階乗関数は、いくつかの異なる方法で定義されています(最初の行は型注釈で、これは省略可能であり、どの実装でも同じです)。
階乗:: (積分a ) => a -> a-- 再帰(「ifthenelse」式を使用)のfactorial n = if n < 2 then 1 else n * factorial ( n - 1 )-- 再帰(パターンマッチングを使用)階乗0 = 1階乗n = n *階乗( n - 1 )-- 再帰(ガード付き)を使用factorial n | n < 2 = 1 | otherwise = n * factorial ( n - 1 )-- リストと「product」関数を使用するfactorial n = product [ 1 .. n ]-- fold(「product」を実装)を使用factorial n = foldl ( * ) 1 [ 1 .. n ]-- ポイントフリースタイルの階乗= foldr ( * ) 1 . enumFromTo 1Haskellの固定小数点コンビネータを使用することで、この関数を明示的な再帰なしに記述できます。
import Data.Function ( fix )階乗= fix fac where fac f x | x < 2 = 1 | otherwise = x * f ( x - 1 )Integer型は任意精度を持つため、このコードはfactorial 100000(456,574桁の数値)のような値を精度を失うことなく計算します。
リストに対するクイックソートに似たアルゴリズムの実装例。最初の要素をピボットとして使用する。
-- 型注釈 (オプション、各実装で同じ) quickSort :: Ord a => [ a ] -> [ a ]-- リスト内包表記を使用quickSort [] = [] -- 空のリストは既にソート済みquickSort ( x : xs ) = quickSort [ a | a <- xs , a < x ] -- リストの左側をソート++ [ x ] ++ -- 2 つのソート済み部分の間にピボットを挿入quickSort [ a | a <- xs , a >= x ] -- リストの右側をソート-- フィルタを使用したクイックソート[] = [] quickSort ( x : xs ) = quickSort ( filter ( < x ) xs ) ++ [ x ] ++ quickSort ( filter ( >= x ) xs )リストされているすべての実装はオープンソースライセンスの下で配布されています。[ 45 ]
Haskell 98規格に完全またはほぼ準拠している実装には、以下のようなものがあります。
現在積極的にメンテナンスされていない実装には以下が含まれます。
Haskell 98に完全に準拠しておらず、Haskellの派生言語を使用している実装には、以下のようなものがあります。
Haskell 用に書かれた注目すべきWeb フレームワークには、次のものがあります。 [ 68 ]
2002年にJan-Willem Maessen、2003年にSimon Peyton Jonesは、遅延評価に関連する問題について議論するとともに、その理論的動機についても言及した。 [ 69 ] [ 70 ]パフォーマンスの向上などの純粋に実用的な考慮事項に加えて、[ 71 ]遅延評価によってプログラマがコードのパフォーマンス(特にメモリ使用量)について推論することがより困難になることを彼らは指摘している。
Bastiaan Heeren、Daan Leijen、および Arjan van IJzendoorn は 2003 年に、Haskell 学習者にとってのいくつかの障害も指摘しました。「Haskell の微妙な構文と洗練された型システムは諸刃の剣です。経験豊富なプログラマーには高く評価されますが、Haskell の汎用性によってしばしば難解なエラー メッセージが表示されるため、初心者にとってはフラストレーションの原因にもなります。」[ 72 ]エラー メッセージに対処するため、ユトレヒト大学の研究者は、Haskell の一部の機能の汎用性を制限することでエラー メッセージの使用性を向上させた Helium と呼ばれる高度なインタプリタを開発しました。特に、型クラスはデフォルトで無効になっています。[ 73 ]
Ben Lippmeier は、Haskell の遅延評価に関する推論や可変配列などの従来のデータ構造の使用における困難に対処するため、型と効果システムを備えた、デフォルトで厳密 (明示的な注釈により遅延) な Haskell の方言として Disciple [ 74 ] を設計しました。[ 75 ]彼は( p . 20 )、「破壊的更新はプログラマに 2 つの重要かつ強力なツールを提供します。オブジェクトのコレクションを管理するための効率的な配列のようなデータ構造のセット、そしてプログラマへの負担を最小限に抑えながらプログラムのすべての部分に新しい値をブロードキャストする機能です」と主張しています。
Standard MLの著者の 1 つですが、Robert Harper氏は、入門プログラミングの教育に Haskell を使用しない理由を述べています。その理由には、厳密でない評価によるリソース使用に関する推論の難しさ、遅延評価がデータ型の定義と帰納的推論を複雑にすること[ 76 ]、Haskell の (古い) クラスシステムが ML のモジュールシステムに比べて「劣っている」こと[ 77 ]などがあります。
Haskell のビルド ツールであるCabalは、同じライブラリの複数のバージョンを適切に処理できないという問題で、これまで批判されてきました。この問題は「Cabal 地獄」として知られています。Stackage サーバーとStackビルド ツールは、これらの批判に対応して作成されました。[ 78 ] Cabal はその後、パッケージ マネージャーNixのアイデアを取り入れることでこの問題に対処し、[ 79 ] 2019 年に新しいアプローチがデフォルトになりました。
CleanはHaskellの近縁で、やや歴史の古い言語です。Haskellとの最大の違いは、入出力(I/O)と副作用にモナドではなく一意性型を使用している点です。
Haskellに触発されつつも、異なる型システムを持つ一連の言語が開発されてきた。例えば以下のようなものがある。
その他の関連言語には以下が含まれます。
注目すべきHaskellの派生版には以下のようなものがある。
Haskell のイベントは、Haskell Symposium (旧 Haskell Workshop) や Commercial Users of Functional Programming などのワークショップを含め、国際関数型プログラミング会議(ICFP)と同時期に定期的に開催されています。 [ 80 ]その他のイベントには、Haskell Implementors Workshop、[ 81 ]チューリッヒの ZuriHac 、[ 82 ]および Hac: The Haskell Hackathon [ 83 ]などがあります。
{{cite news}}: CS1メンテナンス: 場所 (リンク)シーケンス式
と
ワークフロー
と呼ばれる 2 つの高度な言語機能に関して Haskell から影響を受けています
。
言語は、言語のエキスパート、ドキュメント作成の達人、コンパイラ最適化の達人、そしてアイデアの洗練と実地テストに役立つフィードバックを提供してくれた非常に重要な社内ドッグフーディング グループのたゆまぬ努力の産物です。もちろん、Objective-C、Rust、Haskell、Ruby、Python、C#、CLU など、挙げきれないほど多くの言語からアイデアを取り入れ、この分野の他の多くの言語が苦労して得た経験からも大いに恩恵を受けています。
klein-sosp=09が呼び出されましたが、定義されていません (ヘルプ ページを参照してください)。