从箭头表示法转换

时间:2014-08-12 04:24:12

标签: haskell frp arrows netwire

我仍然试图了解箭头表示法与Haskell中定义的箭头类型类的语义之间的相似之处。特别是,this question似乎有一个用箭头符号写的小计数器的非常规范的例子:

counter :: ArrowCircuit a => a Bool Int
counter = proc reset -> do
        rec     output <- returnA -< if reset then 0 else next
                next <- delay 0 -< output+1
        returnA -< output

有人可以告诉我如何在没有箭头符号的情况下将其转换回Haskell2010吗?

2 个答案:

答案 0 :(得分:11)

{- |
                     +---------+
 >Bool>-------------->         |
                     |         >------------------>Int>
       +---------+   |  arr f  |
  /----> delay 0 >--->         >---------\
  |    +---------+   |         |         |
  |                  +---------+         |
  |                                      |
  \--------------------------------------/ 

 -}
counter' :: ArrowCircuit a => a Bool Int
counter' = loop $ second (delay 0) >>> arr f
  where
    f (reset, next) = let output = if reset then 0 else next
                          next' = output + 1
                       in (output, next')

递归rec部分是使用loop实现的。使用resetoutput转换为next(并生成新的next值)的内部部分只是一个具有两个输入和两个输出的纯函数。

答案 1 :(得分:3)

功能代码中的并行性将是使用状态op。在折叠中

import Data.List

counter :: (Int, Int) -> Bool -> (Int, Int)
counter (_, previous_next) reset  =
   let output = if reset then 0 else previous_next
       next = output +1
   in (output, next)

runCounter :: [Bool] -> (Int, Int) 
runCounter = foldl' counter (0,1)

main = do
   let resets = [True, False, True, False, False]   
       result = fst $ runCounter resets
   print result