I would like to represent a circuit with the following behaviour in Haskell:
The circuit has two inputs :
and one output.
True
then output t = input tFalse
, output t = output t-1I need a way to represent the feedback loop, and the state.
I know there is several libraries providing abstractions for this sort of thing, but they look like magic to me.
Is there a simple way to model this?
Edit:
type Signal a = [a]
type Input = Signal Int
type Output = Signal Int
type State = Int
type Switch = Signal Bool
delay :: a -> Signal a -> Signal a
delay = (:)
circuit :: State -> Input -> Switch -> Output
circuit s (i:is) (True:bs) = i : circuit i is bs
circuit s (i:is) (False:bs) = s : circuit s is bs
I used streams to represent the signals, and I carry the state around explicitly in s. But what if I wanted to extract (look at) the elements in the output stream on the fly?
It looks like a problem that the State Monad would solve but I can't find a way to represent it.
Ok I think I finally got how to use the State Monad for this.
Import Control.Monad.State
type Stored a = a
type Input a = a
type Output a = a
type Switch = Bool
circuit :: Input a -> Switch -> State (Output a) (Stored a)
circuit input switch =
do store <- get
if switch
then put input >> return input
else return store
example1 = do circuit 0 False
circuit 2 False
circuit 3 False
res1 = runState example1 $ 4
loopCircuit :: [(Input a, Switch)] -> State (Output a) [(Stored a)]
loopCircuit [] = return []
loopCircuit ((i,s):xs) =
do v <- circuit i s
vs <- loopCircuit xs
return (v:vs)
example2 = runState (loopCircuit [(0,True),(2,False),(3,True)]) 4
The circuit
function can work on discrete inputs, while loopCircuit
can work on a stream of inputs.
res1 = (4,4)
example2 = ([0,0,3],3)