Haskellの駄目な使い方

モナド3点セット(M,ext,unit)のHaskell対応の訂正

最終更新:

匿名ユーザー

- view
メンバー限定 登録/ログイン
#blognavi

をせっかく紹介していただいたんだけど
あとで間違いに気づいてしまいました。

追記:このエントリの内容はすでに檜山さんのモナドの定義とかに書かれておりました。こちらのほうが断然正確で網羅的です。orz


昨日、extは
liftMだよ、、て言っちゃったけど
コレは間違い。

liftM っちゅうのは関数の出入り口をどっちもモナド形で拡張してしまう。

Haskell風の型式でかくと

liftM :: (a -> b) -> (M a -> M b)

で檜山さんがいってた ext はよく読むと

fun:T→Countup(S)という関数から
ext(fun):Countup(T)→Countup(S)
という関数を作り出す関数(高階関数)であるext 

つまり

ext :: (a -> M b) -> (M a -> M b)


で、結局、直接に接対応する関数がみつかりませんですた。
(知らないだけかも。Haskellの偉い人の突っ込みお待ちしております)
追記2:見つかりました

で、無理やり対応付けてみた。

ext = \f -> join.(liftM f)

ここででてきたjoinて関数ってのは

join :: M ( M a ) -> M a

つまり檜山さんのCounterの例でいうと

入れ子になったモナド

{ value: { value:ほげ, counter:5 } , counter:5 }


{ value:ほげ, counter:10 }

にしてくれる関数。

liftM に (a -> M b)な関数 f を適用させると
(M a -> M(M b) )になっちゃうから
joinでつじつまを合わせてる感じ。

#むむ
、joinてCounterMainの代わりに使えそう。
#ひょっとしてjoinてそういう用途なのか

理屈だけじゃなくてIOモナドでちょっと実験。


---- aa.hsで下記をセーブ
module Main where

import Monad

ext :: Monad m => (a -> m b) -> (m a -> m b)
ext = \f -> join.(liftM f)

-- (>>=) と同じものをextで作ってみる。

(>>==) :: Monad m => m a -> (a -> m b) -> m b
m >>== f = (ext f) $ m

-- (>>=)の代わりに動くかな?
main = getLine >>== putStrLn


Hugsで実行。

Main> :l aa.hs
Main> main
abc ←キー入力
abc ←出た!

成功!



カテゴリ: [プログラミング] - &trackback() - 2006年04月20日 12:16:54

#blognavi
目安箱バナー