【関数型言語】学ぶ目的・メリット
単なる好奇心ももちろんある。関数型言語って何ぞ?
実用的な観点として、次のようなもの
最近はプロセッサがマルチコアになり、またスケーラブルなシステムにするためにクラウド上にクラスタを作って動かすシステムが増えている。処理速度を上げるために、並列処理を進めたい。
メジャーな言語(Java, C++など)は、スレッド間でデータを排他処理しなければならないが、適切に設計するのは難しい。
その点、関数型言語は並列化が容易だ。(らしい)それは、すべての関数とデータがイミュータブル(immutable 不変)なので、排他制御が不要になるから。
という理屈はわかった。実感がわかない。なので、並行処理を必要とするアプリケーションで、オブジェクト指向言語と関数型言語で、詳細設計・実装がどのように変わるか、比較してみたい。(いつか)
【関数型言語】ファンクター(関手)
「すごいHaskell楽しく学ぼう!」
第11章「ファンクターからアプリカティブファンクターへ」
11.1 「帰ってきたファンクター」より。
ファンクターとは関数で写せるもののことです。
ファンクターの型クラスメソッドは一つだけで、それは fmap です。fmap の型は fmap :: (a -> b) -> f a -> f b です。
fmap については2通りの考え方ができます。
- fmap は関数とファンクター値をとって、その関数でファンクター地を写して返すものである。
- fmap は値から値への関数をとって、それをファンクター値からファンクター値への関数に持ち上げたものを返す関数である。
【関数型言語】Haskell と Scala の畳み込み関数
Scala とHaskell を比較しながら学んでいる。畳み込み関数について、全く違った表記があった。
- Scala では foldLeft ではなく foldRight がスタックオーバーフローの危険がある。
- Haskell では foldr ではなく foldl がスタックオーバーフローの危険がある。
どういうこと?で、ググった。
Scalaの畳み込み関数
、foldLeft は末尾再帰最適化されているのでスタックを消費しないが、(標準の)foldRight は末尾再帰最適化されていないのでスタックを消費してしまう。foldLeftを使って foldRight を実装すると、スタックオーバーフローを回避できる。
Haskellの畳み込み関数
Haskell はデフォルトで遅延評価なので、foldl でもスタックを消費してしまうらしい。
回避するには、正格(遅延評価しない)な関数 foldl' を使う。かと思いきや、Haskell の場合は foldr のほうが計算量が少ない(高速)という記述もあり混乱中。foldr はスタックオーバーフローしないのか?「foldl は無限リストを扱えないが、foldr は無限リストを扱える」らしい。このこととスタックの使い方はどうなっている?