Workshop/StartHaskell2/exercise11

『ファンクターからアプリカティブファンクターへ』 練習問題

Functerインスタンスを考える

次のもののFuncterインスタンスを考えてみよう。実装はファンクター則を満たしているだろうか。また、それ以外の実装はありえるだろうか。

たとえばリストだったら、以下のように書く。

ヒント:

次のMaybeのFuncter実装は、ファンクター則を満たしているだろうか。

参考:The Typeclassopedia


ファンクター則を破るとどうなるの?

今、a, b, c, f, g の5つの関数の間に、次の恒等式が成り立っているとする。

それぞれの関数をファンクターで写したとき、以下のような同じ恒等式が成り立つだろうか。ファンクター則が成り立つときと、成り立たないときについて、確認してみよう。

参考:ファンクター則は、一般的には準同型と呼ばれる。 ja.wikipedia.org/wiki/準同型


ファンクターを使って書き直す

次のコードをファンクターを使って書き直してみよう。


モナドをアプリカティブに書き直す

次のIOモナドを使ったコードを、アプリカティブスタイルに書き直してみよう。

次のコードもアプリカティブスタイルに書き直してみよう。


パーサーコンビネータ

次のBNFを考える。

<formula> ::= 0 | 1 | 2 | 3 |
              -<formula> | (<formula>*<formula>) | (<formula>+<formula>)

これを解析して計算するパーサーコンビネーターをモナドスタイルで書いたのが次のコードである。これの number, minus, times, add 関数をアプリカティブスタイルに書き直してみよう。

実行例:echo "(2*3)" | runghc parser.hs

ヒント:Applicativeのススメに、アプリカティブを使ったパーサーコンビネーターの書き方が載っています。

Control.Applicativeにある、次の関数を駆使する必要があります。

たとえば times 関数をアプリカティブに書き直すと、こんな感じです。

出典:ACM国際大学対抗プログラミングコンテスト 2008 国内予選 問題C の改変


ZipList

ZipListを使って、Data.Listにあるtranspose関数を実装してみよう。

テキスト(p.253)にある sequenceA 関数と比較してみよう。

参考:Conor McBride and Ross Paterson. Applicative Programming with Effects. J. Funct. Program., 18(1):pages 1-13 (2008).