Haskell中带有反馈环路的顺序电路

时间:2015-11-18 07:52:38

标签: loops haskell sequential feedback circuit

我想在Haskell中表示具有以下行为的电路:

电路有两个输入:

  • 数据输入
  • 和开关输入

和一个输出。

  • 当开关= True然后输出 t = input t
  • 当switch = False时,输出 t = output t-1

我需要一种方法来表示反馈循环和状态。

我知道有几个图书馆为这类事情提供了抽象,但它们对我来说看起来很神奇。

有一种简单的方法可以对此进行建模吗?

编辑:

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

我使用流来表示信号,并且我在s中明确地携带状态。但是如果我想在运行中提取(查看)输出流中的元素呢?

状态Monad会解决这个问题,但我找不到代表它的方法。

2 个答案:

答案 0 :(得分:7)

对于它的价值:这个问题非常适合Haskell的一些独特而强大的抽象,例如MonadArrow。但是那些花费时间和经验来学习,我猜你的措辞是你对它们并不熟悉。如果你留在Haskell,我建议将来再次重新审视这个问题以获得启示。我不会花更多的时间在这些事情上。

您可以简单地通过无限列表对离散时变信号建模:

type Signal a = [a]

zeroS, oneS :: Signal Bool
zeroS = repeat False
oneS  = repeat True

您可以使用zipWith逐点组合信号。例如:

andS :: Signal Bool -> Signal Bool -> Signal Bool
andS = zipWith (&&)

ghci> andS zeroS oneS
[False,False,False,False,False,False,False,False,...

您可以通过列表开头的信号将信号延迟1个单位时间。这需要信号的初始值。

delay :: a -> Signal a -> Signal a
delay x s = x : s
-- or just
-- delay = (:)

在您的问题中,您描述了这种类型的函数:

circuit :: Signal Bool -> Signal Bool -> Signal Bool
circuit switch input = ...

您可以使用这些概念和递归来构建。祝你好运!

答案 1 :(得分:0)

好的,我想我终于得到了如何使用State Monad。

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

circuit函数可以处理离散输入,而loopCircuit可以处理输入流。

res1 = (4,4)
example2 = ([0,0,3],3)