みどりねこ日記

よくわからないけど、頑張りますよ。

モナドトランスフォーマー の検索結果:

Haskellモナドトランスフォーマー(12)

…う2つの非常に単純なモナドトランスフォーマーの実装をしてきました。それから、少し遠回りをしてモナドをそれのトランスフォーマーに持ちあげるという話もしましたね。ここでは、その二つの考えを、StateTという標準ライブラリの中でも興味深いトランスフォーマーの実装を見ながらつなげてみましょう。このトランスフォーマーを学ぶことで、モナドトランスフォーマーをコードの中で使用するときに、トランスフォーマーのメカニズムがはっきりと見えてくるようになります。もしもわかりにくかったら、過去のS…

Haskellモナドトランスフォーマー(11)

liftの実装はわりと素直です。MaybeTトランスフォーマーの場合を見てみます。 instance MonadTrans MaybeT where lift mon = MaybeT (mon >>= return . Just) 内側のモナドを値に適用し、サンドイッチで言う真ん中までの処理を行ったあと、>>=演算子と型コンストラクタを使用して最下層のモナドを真ん中のスライスの下に潜り込ませます。その後、MaybeTコンストラクタを使用してサンドイッチを完成させます。関数l…

Haskellモナドトランスフォーマー(10)

モナドトランスフォーマーによって合成されたモナドを使うとき、内側のモナドをきちんと考える必要がないようにしたいところです。そのほうが綺麗でシンプルなコードになるからです。内側のモナドの型を持った値を扱う計算の中でdoブロックを使うより、内側のモナドを合成モナドまで持ち上げる命令を使ったほうが良いでしょう。liftMは、モナディックでない関数をモナドに持ち上げる関数だったことを思い出してください。各モナドトランスフォーマーはモナディックな計算を合成モナドに持ち上げる関数lift…

Haskellモナドトランスフォーマー(9)

標準ライブラリの中でも、とりわけ使いやすい関数の一つに、liftMがあります。モナディックでない関数をモナドの関数に持ち上げます。型を見てみましょう。 liftM :: Monad m => (a1 -> r) -> m a1 -> m r さて、liftMは関数(a1 -> r)と、a1を保持したモナドをとり、受け取った関数をa1に適用し、mに包んで結果を返します。この関数を理解するには、どのように使われるかを見るのが一番です。以下のコードはすべて同じ意味を持ちます。 do…

Haskellモナドトランスフォーマー(8)

次はリストトランスフォーマーを考えましょう。 Maybeトランスフォーマーのように、1つ引数をとるコンストラクタ付きのデータ型を定義します。 newtype ListT m a = ListT { runListT :: m [a] } ListTモナドの実装も、もとのListモナドのそれと非常に似通っています。 Maybeのものと比べると内側のモナドに対する処理が少し増えていますが、基本的は同じで、モナドのサンドイッチ(ListT - m - List)をはがして新たに生成…

Haskellモナドトランスフォーマー(7)

さて、前回の記事では>>=演算子を実装しました。しかし、実際のところ、何が起きているのでしょうか。 (>>=)演算子は、サンドイッチの層を一枚ずつ剥がし、中の値に関数を適用し、その結果である新たな値を新しいサンドイッチの中に詰めて返すのだと考えても良いです。 サンドイッチから値を引っ張りだす MaybeTコンストラクタについては一旦忘れましょう。$のあとにつづく処理はmモナドの中で実行されているのであり、MaybeTモナドの中ではないことに注意してください。 最初に、runM…

Haskellモナドトランスフォーマー(6)

…りやすく考えるなら、モナドトランスフォーマーをサンドイッチとして考えましょう。サンドイッチの下が元のモナド(ここではMaybe)、中身が「内なるモナド」m、そして一番上がモナドトランスフォーマーMaybeTです。関数runMaybeTの存在意義は、この一番上のモナドトランスフォーマーMaybeTを取り除くことです。runMaybeTの型は(MaybeT m a) -> m (Maybe a)です。改めて言いますが、モナドトランスフォーマー自身もモナドです。MaybeTモナドの…

Haskellモナドトランスフォーマー(5)

モナドトランスフォーマーがいかにして動いているのかは、どのように>>=演算子が実装されているかを理解するとわかるでしょう。>>=演算子の実装は、トランスフォーマーではない、もとのモナドのそれと非常に似ていることがわかると思います。トランスフォーマーの型コンストラクタについて説明します。型コンストラクタはHaskellのモナドの基幹となるものです。Reader r aが、環境rのついたReaderモナドの中にある型aの値の型であることを思い出してください。型コンストラクタRea…

Haskellモナドトランスフォーマー(4)

モナドトランスフォーマーはモナドの結合を簡単にするモナドの、特別な種類です。例えば、ReaderT Env IO aはEnv型の環境から読み取り、IOを行い、型aを返すことができる計算です。モナドトランスフォーマーの型コンストラクタはモナドのそれにパラメータ化されており、モナディックな型を生成します。モナドの仕組みがわかっていることを前提に話すので、もしかしたらわかりにくいかもしれません。そういったときは、Haskellのモナド(結構前の記事)あたりを見ていただけたらと思いま…

Haskellモナドトランスフォーマー(3)

さて、準備が整ったので、getPasswordやそれを利用するコードを書きなおしてみましょう。 getValidPassword :: MaybeT IO String getValidPassword = do s <- lift getLine guard (isValid s) return s askPassword :: MaybeT IO () askPassword = do lift $ putStrLn "Insert your new password: …

Haskellモナドトランスフォーマー(2)

…モナドの特性を与えるモナドトランスフォーマーを定義します。これを、モナドトランスフォーマーの慣例的な名付け方に従い、最初に与える特性を持つモナドの名前+Tとし、MaybeTと呼びます。MaybeTは、m (Maybe a)のラッパーで、mにはどのようなモナドも入ることが出来ます。(ここではIOに注目します。) newtype (Monad m) => MaybeT m a = MaybeT {runMaybeT :: m (Maybe a)} アクセサ関数runMaybeTを…

Haskellモナドトランスフォーマー(1)

…で、これからしばらくモナドトランスフォーマーについて書いていきます。これは特別な型で、モナドに適用した時、新たな合成されたモナドを生成します。このモナドはそのどちらの性質も持ち合わせることになります。IT業界に生きる上で、ユーザーにパスワードを強固なものにするようにすすめるプログラムという、よくある問題を例にして考えてみます。一般的な解決方法として、ユーザがパスワードを設定する時、そのパスワードが最低限の長さをもち、かつ1文字以上のアルファベット、1文字以上の数値、などといっ…