I recommend that you look Control.Arrow, in particular , and . This tutorial is also very good. (***)(&&&)(>>>)
(***) allows you to take two arrows and place them next to each other in the arrow, which has both inputs and outputs (in the form of tuples):
(***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c')
(&&&) allows you to combine the two arrows again and get a tuple of their output, but this time both arrows will use the same input:
(&&&) :: Arrow a => a b c -> a b c' -> a b (c, c')
(>>>) . . , (>>>) (.) Control.Category .
(>>>) :: Arrow a => a b c -> a c d -> a b d
( Category, .)
andGate, nandGate xorGate:
-- Use (x NAND y) === ((NOT x) OR (NOT y))
nandGate :: Circuit circ => circ (Bool, Bool) Bool
nandGate = (notGate *** notGate) >>> orGate
-- Use (x NAND y) === (NOT (x NAND y))
andGate :: Circuit circ => circ (Bool, Bool) Bool
andGate = nandGate >>> notGate
-- Use (x XOR y) === ((x OR y) AND (x NAND y))
xorGate :: Circuit circ => circ (Bool, Bool) Bool
xorGate = (orGate &&& nandGate) >>> andGate
-XArrows
, Arrow do - . , Control.Arrow, .
{-# LANGUAGE Arrows #-}
nandGate :: Circuit circ => circ (Bool , Bool ) Bool
nandGate = proc (x,y) -> do
x' <- notGate -< x
y' <- notGate -< y
orGate -< (x',y')
andGate :: Circuit circ => circ (Bool, Bool) Bool
andGate = proc (x,y) -> do
z <- nandGate -< (x,y)
notGate -< z
xorGate :: Circuit circ => circ (Bool, Bool) Bool
xorGate = proc (x,y) -> do
z <- orGate -< (x,y)
w <- nandGate -< (x,y)
andGate -< (z,w)