29

特に McBride と Paterson による Functional Pearl で、Applicative functor について読んでいます。しかし、いくつかの演習を行って理解を固めたいと思います。私はプログラミングの演習が好きですが、証明の演習も問題ありません。 アプリカティブ ファンクターを使った効果的なプログラミングを学ぶには、どのような演習が役立ちますか?

個々のエクササイズは、他の場所にリストされているエクササイズへのポインターと同様に問題ありません。

4

4 に答える 4

22

答えとしていくつかの質問を投稿するのは面白いようです。これは、数独に基づいたApplicativeとの間の相互作用に関する楽しいものです。Traversable

(1)検討する

data Triple a = Tr a a a

構築する

instance Applicative Triple
instance Traversable Triple

Applicativeインスタンスが「ベクトル化」を実行し、インスタンスTraversableが左から右に機能するようにします。適切なインスタンスを作成することを忘れないでください。またはインスタンスFunctorのいずれかからこれを抽出できることを確認してください。あなたは見つけるかもしれませんApplicativeTraversable

newtype I x = I {unI :: x}

後者に役立ちます。

(2)検討する

newtype (:.) f g x = Comp {comp :: f (g x)}

それを示す

instance (Applicative f, Applicative g) => Applicative (f :. g)
instance (Traversable f, Traversable g) => Traversable (f :. g)

今定義する

type Zone = Triple :. Triple

Boardを水平ゾーンの垂直ゾーンとして表すとします。

type Board = Zone :. Zone

の機能を使用して、垂直ゾーンの水平ゾーンとして、および正方形の正方形として再配置する方法を示しますtraverse

(3)検討する

newtype Parse x = Parser {parse :: String -> [(x, String)]} deriving Monoid

または他の適切な構造(Monoid| Maybe |のライブラリの動作が不適切であることに注意してください)。構築する

instance Applicative Parse
instance Alternative Parse  -- just follow the `Monoid`

実装します

ch :: (Char -> Bool) -> Parse Char

これは、特定の述語によって受け入れられた場合に文字を消費して配信します。

(4)任意の量の空白を消費するパーサーを実装し、その後に1桁の数字を続けます(0はブランクを表します)

square :: Parse Int

およびを使用puretraverseて構築する

board :: Parse (Board Int)

(5)定数関手を考慮する

newtype K a x = K {unK :: a}

構築します

instance Monoid a => Applicative (K a)

次に、を使用traverseして実装します

crush :: (Traversable f, Monoid b) => (a -> b) -> f a -> b

接続詞および論理和のモノイド構造を表現するためnewtypeのラッパーを作成します。のバージョンを実装するためにBool使用し、どのファンクターでも機能します。crushanyallTraversable

(6)実装

duplicates :: (Traversable f, Eq a) => f a -> [a]

複数回発生する値のリストを計算します。(完全に些細なことではありません。)(微分計算を使用してこれを行うための素敵な方法がありますが、それは別の話です。)

(7)実装

complete :: Board Int -> Bool
ok :: Board Int -> Bool

これは、ボードが(1)[1..9]の数字のみでいっぱいであり、(2)行、列、またはボックスに重複がないかどうかをチェックします。

于 2012-04-20T08:22:17.447 に答える
12

練習するのに最適な方法はParsec、モナディックスタイルではなくアプリケーションで使用することです。doほとんどのパーサーは純粋に適用可能であるため、表記法を使用する必要はありません。

例えば。式の場合:

import qualified Text.Parsec as P
import qualified Text.Parsec.Token as P
import Control.Applicative

data Expr = Number Int | Plus Expr Expr

lex = P.makeTokenParser ...  -- language config

expr = number <|> plus
    where
    number = Number <$> P.integer lex
    plus = Plus <$> number <* P.symbol lex "+" <*> expr
于 2012-04-20T03:43:20.733 に答える
5

Typeclassopediaをチェックしてください。それはゼロからの良い説明と途中でいくつかの練習が付属しています。

于 2012-04-20T03:03:15.727 に答える
4

例:Applicative Functors

于 2012-04-20T03:10:58.157 に答える