論理回路

いろいろなサイトを読みながら意味もわからず書いたコード。c1 は論理回路の定義です。Arrow はモナドの一般化らしいです。やっぱりよくわかりません。とりあえず

proc arg -> do ...

みたいな書き方は、コンパイル時に "-farrows" を付けないと使えません。

{-# OPTIONS -farrows #-}
import Control.Arrow

orG, andG, xorG :: Arrow a => a (Bool, Bool) Bool
andG = proc (a,b) -> returnA -< a && b
orG  = proc (a,b) -> returnA -< a || b
xorG = proc (a,b) -> returnA -< a && not b || not a && b
notG :: Arrow a => a Bool Bool
notG = proc a -> returnA -< not a

nandG, norG :: Arrow a => a (Bool, Bool) Bool
nandG = andG >>> notG
norG  = orG  >>> notG

c1 = proc (x1,x2,x3,x4) ->
       do nx2 <- notG -< x2
          t1 <- orG -< (x1,nx2)
          t2 <- nandG -< (x1,x3)
          t3 <- andG -< (x2,x4)
          t4 <- xorG -< (t2,t3)
          returnA -< nandG (t1,t4)

tester c = mapM_ f $ tester'
    where tester' = do x1 <- [True, False]
                       x2 <- [True, False]
                       x3 <- [True, False]
                       x4 <- [True, False]
                       return [x1,x2,x3,x4,c1 (x1,x2,x3,x4)]
          f x = print $ map (?x -> if x then 1 else 0) x