私は、特にMcBrideとPatersonのFunctional Pearlのアプリケーションファンクタについて読んできました。しかし、私はいくつかの練習をして私の理解を固めたいと思います。私はプログラミング演習を好むだろうが、実証演習もOKです。 練習問題を教えてください。アプリケーションファンクタのプログラミング演習はどこにありますか?
個々の演習は、別の場所にリストされている演習の指針と同様です。
私は、特にMcBrideとPatersonのFunctional Pearlのアプリケーションファンクタについて読んできました。しかし、私はいくつかの練習をして私の理解を固めたいと思います。私はプログラミング演習を好むだろうが、実証演習もOKです。 練習問題を教えてください。アプリケーションファンクタのプログラミング演習はどこにありますか?
個々の演習は、別の場所にリストされている演習の指針と同様です。
答えとしていくつかの質問を投稿すると面白いようです。これは、スードクに基づいて、Applicative
とTraversable
の間の相互作用の楽しいものです。 Applicative
インスタンスは、 "ベクトル" とTraversable
インスタンスが左から右に動作しないように
(1)
data Triple a = Tr a a a
は
instance Applicative Triple
instance Traversable Triple
を構築することを検討します。適切なFunctor
インスタンスを構築することを忘れないでください:Applicative
インスタンスまたはTraversable
インスタンスのいずれかからこれを抽出できることを確認してください。あなたは見つけることができます
newtype I x = I {unI :: x}
は、後者に役立ちます。
(2)
newtype (:.) f g x = Comp {comp :: f (g x)}
すぐ
type Zone = Triple :. Triple
を定義
instance (Applicative f, Applicative g) => Applicative (f :. g)
instance (Traversable f, Traversable g) => Traversable (f :. g)
我々は、水平ゾーンの垂直ゾーン
としてBoard
を表すと仮定していることを表示検討
水平ゾーンの水平ゾーンとして再配置する方法と、正方形の正方形としてtraverse
の機能を使用して再配置する方法を示します。
(3)(不適切である| |たぶんためのライブラリMonoid
行動があることに留意)
newtype Parse x = Parser {parse :: String -> [(x, String)]} deriving Monoid
またはいくつかの他の適切な構造を考えてみましょう。
instance Applicative Parse
instance Alternative Parse -- just follow the `Monoid`
を構築し、それが与えられた述語によって受け入れられた場合、文字を消費し、提供
ch :: (Char -> Bool) -> Parse Char
を実装します。
(4)
board :: Parse (Board Int)
(5)を構築する
square :: Parse Int
使用pure
とtraverse
(0は空白を表す)単一の数字が続く、空白の任意の量を消費するパーサを実装定数ファンクタを考える。
newtype K a x = K {unK :: a}
とconstru CT
instance Monoid a => Applicative (K a)
はその後
crush :: (Traversable f, Monoid b) => (a -> b) -> f a -> b
はその連言と選言モノイド構造を表現するためのBool
newtype
ラッパーを構築し実装するためtraverse
を使用しています。 Traversable
ファンクタで動作するany
とall
のバージョンを実装するには、crush
を使用してください。
(6)複数回発生した値のリストを計算
duplicates :: (Traversable f, Eq a) => f a -> [a]
実装。 (完全に容易ではありません。)(あり、この使用して、差分計算を行うには素敵な方法だが、それはまた別の話だ。)
は(7)ボードがあるかどうかを確認
complete :: Board Int -> Bool
ok :: Board Int -> Bool
を実装(1)フルのみ行、列またはボックスに重複がない[1..9]および[2]の数字の数。
すばらしいエクササイズ! – luqui
Typeclassopediaをご覧ください。それは、地面からの良い説明と道に沿ったいくつかの練習が付属しています。例えば
このリンクは死んでいるようですが、[これはインターネットアーカイブウェイバックマシンのページです](https://web.archive.org/web/*/http://www.cis.upenn.edu/~cis194/lectures/ *): [Functors](https://web.archive.org/web/20130803145920/http://www.cis.upenn.edu/~cis194/lectures/09-functors.html); [該当するファンクタ](https://web.archive.org/web/20130803134207/http://www.cis.upenn.edu/~cis194/lectures/10-applicative.html) –
は練習するのに最適な方法ではなく、モナドスタイルよりも、応用的で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
私は興味があります - あなたはアプリケーションファンクターでは解析できないが、モナドではできないいくつかの一般的な、あるいは少なくとも合理的な例を与えることができますか? –
@TikhonJelvis、*正式には、少なくとも有限のアルファベット以上の力ではあるが、病理学的な方法(無限の文法をサポートしている)である。しかし、あなたがモナドを必要とする場所の良い例は、構文解析の後半で考慮すべき新しい文法構造を定義できる言語を持っていれば可能です。'Applicative'は、*コンテンツ*に基づいて構造体を変更することはできません、' Monad' can。 – luqui
+1タイトルを見たとき、私はすぐにパーセルを考えました。これは面白くて重要ではない単純な問題を解決する練習に最適な方法です。 –
私は練習問題を提案することはできませんが、モナドではないアプリケーションファンクタを見ることができます(重要な質問は「なぜモナドよりも強力ではない場合に、アプリケーションファンクタを設計するのですか? Andy GillとKevin MatledgeのChalkboardのアニメーションの1つであるAnda Gillと同僚のKansas Lavaは、応用ファンクタをベースにしていると考えています(PatersonとMcBrideのマルチエラーアプリケーションは1つです)。 –