用箭头建模电路

时间:2016-11-25 23:21:55

标签: haskell arrows

我有:

class Arrow circ ⇒ Circuit circ where
    wire    :: circ Bool Bool
    notGate :: circ Bool Bool
    orGate  :: circ (Bool , Bool ) Bool

    wire = id
    notGate = arr not
    orGate = arr $ uncurry (||)

我想实施:

-- A and B
andGate :: Circuit circ ⇒ circ (Bool , Bool ) Bool
-- not (A and B)
nandGate :: Circuit circ ⇒ circ (Bool , Bool ) Bool
-- A xor B
xorGate :: Circuit circ ⇒ circ (Bool , Bool ) Bool

我不想使用像(arr和)这样简单的东西,但结合已有的功能。我没有理解如何用函数来组合箭头。

谢谢。

1 个答案:

答案 0 :(得分:3)

我建议您查看Control.Arrow,特别是(***), (&&&), and (>>>)This tutorial也非常好。

  • (***)允许你拿两个箭头并将它们并排放入一个既有输入又有输出的箭头(作为元组):

    (***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c')
    
  • (&&&)让你再次组合两个箭头并获得他们输出的元组,但这次两个箭头将消耗相同的输入:

    (&&&) :: 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,但这不是重点。)

然后,我们可以使用一些常见的逻辑等价来获得andGatenandGatexorGate

-- 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)