これはElm Advent Calendar 2014の3日目です。
ElmはHaskellベースの言語なので、Haskellの記事や入門書もElmの学習に使えます。しかし、実はElmにはチョコチョコHaskellと違うところがあって互換性はありません。
相違点をElm公式サイトLearnの SyntaxとFAQから抜粋して解説します。
1. Elmは遅延評価ではありません
Haskellは遅延評価なのでリスト処理の効率が良いのがウリでした。 JavaScriptにもジェネレータという形で遅延評価の思想が取り入れられています。
しかし、Elmのリストや辞書等などは遅延評価ではありません。
Elmはクライアントサイドの言語なので、遅延評価があまり役立たないこと、
Signal
がJavaScriptのジェネレータのような機能を持っているためのようです。
2. Elmにモナドはありません
Signal
があるので、IOモナドは不要です。それどころかMaybeモナドもListモナドもありません。したがって、do文もありません。
なお、Maybeは標準ライブラリにMaybe
パッケージがあり、JavaScriptでnull
を使うようなコードを安全に書けます。
でも、やっぱりdo文はあった方がいいと私は思うことがあります・・・。case
を5段階ぐらいネストしたりすると。
まぁ「モナドは圏論に基づいています*1」という説明が「Haskellってモナドが難しいんでしょ?」という誤解を生むことがないからいいのかな?
3. 関数関連の演算子が違う
Elm | Haskell | 意味 | 同値なJavaScript | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
f x <| g y z
|
$
と.
がそれぞれ<|
と<<
に変わっています。そして引数の順番を逆にした>|
と>>
が加わっています。
4. ::
と:
の意味が逆
Elm | Haskell |
---|---|
norm : Float -> Float -> Float norm x y = sqrt (x * x + y * y) |
norm :: Float -> Float -> Float norm x y = sqrt (x * x + y * y) |
1 :: 2 :: alist == [1, 2] ++ alist |
1 : 2 : alist == [1, 2] ++ alist |
これは型アノテーションの方がリストへの追加よりも頻繁に使うからです。
5. foldl系関数の引数の順序が逆
List.foldr
, List.foldl
はリストの要素に次々に関数を適用する関数です。
データ構造毎にDict.foldl
、Set.foldl
といった変種もあります。他言語ではreduce
やinject
という名前で提供されていることがあります。
// elm v = List.foldr (+) 0 [1,2,3] // 同等なJS var list = [1, 2, 3]; var v = 0; for (var i = 0; i < list.length; i++) { v = v + list[i]; }
微妙な違いですがElmではList.foldl
が受け取る関数の引数の順序をあえてHaskellと逆にしてあります。
Elm | Haskell | ||
---|---|---|---|
List.foldl : (a -> b -> b) -> b -> [a] -> b
|
これは、Elmでは標準ライブラリを「データ構造はいつも最後の引数」というルールで設計しているのに関係しています。
たしかに、HaskellのようにList.foldl : (b -> a -> b) -> b -> [a] -> b
であったとすると、foldr
にはそのまま使えるのにfoldl
には使えない関数が出てきて困る気がしますが・・・私にはよく分かりませんでした。
公式サイトのLibrary Design Guidelinesにその点が書いてあるのですが、例がおかしい(間違っている?古い?)気がします。
6. 他にも色々なものがありません。
- do文以外のモナド関連の構文や演算子
- where文。代わりにletを使う
(+1)
のような記法。代わりに((+) 1)
と書く- ライブラリ
こんなに違って大丈夫?
Haskellは元もと演算子が多い(多すぎる?)言語なので、ElmではSignalが入って互換性がなくなるなら演算子も整理したいと言うことなのでしょう。
ただ「HaskellのライブラリがElmに流用できない」という懸念をもつ方もいらっしゃると思います。私も不安です。
しかし、Haskellは主にサーバーサイドやコンパイラなどに使われ、Elmはクライアントサイドのための言語なので、「ブラウザ上で動くコンパイラを作りたい」というのでもなければ、HaskellのライブラリをElmに流用する機会は実は無いのかもしれません。
あとがき
更新が24時を過ぎてしまいました。
Elm Advent Calendar 2014にはまだ空きがあります。ふるってご参加ください。
- 作者: Miran Lipovača,田中英行,村主崇行
- 出版社/メーカー: オーム社
- 発売日: 2012/05/23
- メディア: 単行本(ソフトカバー)
- 購入: 25人 クリック: 580回
- この商品を含むブログ (67件) を見る
*1:確かにモナドは圏論にルーツがありますが、 「『変数』はデカルトにルーツがあります」「正規表現はオートマトン理論に基づいています」「while文を使用することで原始計算可能な関数だけでなく真に計算可能な関数を作成することが可能になります」ってあえて説明したりしないでしょう?「モナドは圏論(ry」が使われる背景には、数学という虎の威を借りてHaskellを高尚に見せようとする心理があるように私には思えます。