週に一回は書きますよ 月に4つ記事を書けばノルマは満たされます。
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
気が向いたので、Arrow調査 回答編のコードにインデントをつけてみます。 がりがりっと
import Control.Arrow
import Control.Monad
import Control.Monad.State

type LogState = State (Int,String)
type LogArrow  = Kleisli LogState

withLog :: (Show a,Show b) => String -> LogArrow a b -> LogArrow a b
withLog name a = Kleisli act where
                -- この型宣言だとエラーが出ます。どう書くべきなのでしょうか。
                -- act :: (Show a,Show b) => a -> LogState b
                act x = do
                        (indent,mes) <- get
                        let tab = replicate indent '\t'
                        put (indent+1, mes++tab++name++" "++show x++"\n")
                        res <- runKleisli a x
                        (indent2,mes2) <- get
                        let tab2 = replicate indent2 '\t'
                        put (indent, mes2++tab2++"return "++show res++"\n")
                        return res

orGate,andGate :: LogArrow (Bool,Bool) Bool
andGate = withLog "AND" $ arr $ uncurry (&&)
orGate  = withLog "OR"  $ arr $ uncurry (||)

inverter :: LogArrow Bool Bool
inverter = withLog "NOT" $ arr not

halfAdder :: LogArrow (Bool,Bool) (Bool,Bool)
halfAdder = withLog "HalfAdder" $
                        proc (a,b) -> do
                d <- orGate -< (a,b)
                c <- andGate -< (a,b)
                e <- inverter -< c
                s <- andGate -< (d,e)
                returnA -< (s,c)

fullAdder :: LogArrow (Bool,Bool,Bool) (Bool,Bool)
fullAdder = withLog "FullAdder" $
                proc (a,b,cIn) -> do
                        (s2,c2) <- halfAdder -< (b,cIn)
                        (s1,c1) <- halfAdder -< (a,s2)
                        cOut <- orGate -< (c1,c2)
                        returnA -< (s1,cOut)

main :: IO ()
main = do
        let (_,str) = execState (runKleisli fullAdder (True,True,True)) (0,"")
        putStr str

とりあえずfullAdderまで。StateTとかを使うのは面倒だったので、Stateにインデントの深さと出力すべき文字列とを保持するようにしました。IOはmainだけに封印。

ところでコメントにあるとおり、withLogの途中の関数の関数宣言がうまく出来ません。 解法募集中。

まあそれは当面問題はないのでコンパイルします。

arrowst.o(.text+0x56):fake: undefined reference to `ControlziMonadziState_zdfMon
adStates_closure'
arrowst.o(.text+0xc6):fake: undefined reference to `ControlziMonadziState_zdfMon
adStates_closure'
arrowst.o(.text+0x3d9):fake: undefined reference to `ControlziMonadziState_zdfMo
nadStates_closure'
arrowst.o(.text+0x929):fake: undefined reference to `ControlziMonadziState_zdfMo
nadStates_closure'
arrowst.o(.text+0x339a):fake: undefined reference to `ControlziMonadziState_exec
State_closure'
arrowst.o(.text+0x34a3):fake: undefined reference to `__stginit_ControlziMonadzi
State_'
arrowst.o(.rodata+0x0):fake: undefined reference to `ControlziMonadziState_zdfMo
nadStates_closure'
arrowst.o(.rodata+0x4):fake: undefined reference to `ControlziMonadziState_zdfMo
nadStates_closure'
arrowst.o(.rodata+0x10):fake: undefined reference to `ControlziMonadziState_zdfM
onadStates_closure'
arrowst.o(.rodata+0x158):fake: undefined reference to `ControlziMonadziState_exe
cState_closure'
collect2: ld returned 1 exit status
なんなんですか。なんで急にリンクエラー起こすんですか。<TM>

検索したら同じところで引っかかった人を見つけました。http://d.hatena.ne.jp/rahAloe/20060617/p1

どうも必要なパッケージ(MonadTrans関連?)がリンクされないようです。 リンク先にあるとおり、--makeオプションをつければ大丈夫でした。

実行結果

FullAdder (True,True,True)
        HalfAdder (True,True)
                OR (True,True)
                        return True
                AND (True,True)
                        return True
                NOT True
                        return False
                AND (True,False)
                        return False
                return (False,True)
        HalfAdder (True,False)
                OR (True,False)
                        return True
                AND (True,False)
                        return False
                NOT False
                        return True
                AND (True,True)
                        return True
                return (True,False)
        OR (False,True)
                return True
        return (True,True)

おお美しい。われながら良く出来たような気がします。

ところでこのコード、arrowというよりmonadの練習ですね。

スポンサーサイト
コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
http://gusmachine.blog49.fc2.com/tb.php/24-436d0e93
この記事にトラックバックする(FC2ブログユーザー)
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。