1と2のリビジョン間の差分
2013-06-23 00:21:17時点のリビジョン1
サイズ: 2781
編集者: grafi
コメント:
2013-06-23 00:22:16時点のリビジョン2
サイズ: 2776
編集者: grafi
コメント:
削除された箇所はこのように表示されます。 追加された箇所はこのように表示されます。
行 9: 行 9:
    ::: Haskell     :::Haskell
行 17: 行 17:
    ::: Haskell     :::Haskell
行 24: 行 24:
    ::: Haskell     :::Haskell
行 31: 行 31:
    ::: Haskell     :::Haskell
行 38: 行 38:
    ::: Haskell     :::Haskell

Applicativeのこと少し

スライドに「Monadのような計算(の一部)を applicative style(要は普通の関数型言語の書き方)で書けるようにする」と書いていますが、ちょっと何を言っているのか分からないかもしれません。

pricesにくだものの名前と値段の連想リストが入っているとして、二つの果物を買うのに必要な値段は

buy2 fruit1 fruit2 =
  lookup fruit1 prices >>= \pri1 ->
  lookup fruit2 prices >>= \pri2 ->
  return pri1 + pri2

と書けますが、もしlookupの返り値がMaybeでなければ

buy2' fruit1 fruit2 = (lookup fruit1 prices) + (lookup fruit2 prices)

と書くところです。Maybeモナドの文脈で計算させたいだけなのに、余計なpri1とかpri2とかいう変数が出てきて、ちょっと気持ち悪いと思いませんか?

Applicativeスタイルで書くと以下のようになります。

buy2 fruit1 fruit2 = (+) <$> lookup fruit1 prices <*> lookup fruit2 prices

Haskellでは二項演算子はただの関数で、演算子っぽい名前がついた関数は中置記法で書くことができるものの、(+)という風に括弧で括って使うと、普通の関数と全く同じように前置記法で適用できることに注意が必要です。

心眼で余計な演算子を消す(Lisperが括弧を消すようなもの)と、

buy2' fruit1 fruit2 = (+) (lookup fruit1 prices) (lookup fruit2 prices)

と読むことができます。

つまりは

buy2' fruit1 fruit2 = (lookup fruit1 prices) + (lookup fruit2 prices)

ですね。

読みにくいだけだと思うかもしれないですが、この例くらいなら慣れれば読みやすくなる、という感じですかね。Applicativeに限った話ではないですが、気持ち悪い見た目には現実問題として慣れるしかないものの、本来は言語とかライブラリとかを作った側の責任であって、読みづらいと感じる自分は無能だとか感じる必要はないと思います。

Monadよりも力が限定されている分、Applicativeには無駄に混みいった制御構造を作ってしまいにくいというメリットがあります。Applicativeすごいんだよという話はApplicative Programming with Effectsに載っています(読んでません)。

GADT

言語内DSLに便利

言語内DSLでの関数の表現が大変

PHOAS

Parameterのkindは*->*だよ


FLProgClassCategory

grafi/Haskell課題(GADTなど) (最終更新日時 2013-07-01 19:11:35 更新者 alpicola)