I am reading John Hughes's Programing with Arrows. There is a piece of code that I really cannot understand. The code is following:
import Control.Arrow.Operations
import Control.Arrow
import Control.Category
import Prelude hiding ((.),id)
newtype SF a b = SF {runSF :: [a] -> [b]}
instance Category SF where
id = SF id
(.) (SF f) (SF g) = SF $ \x -> f (g x)
(.*.) :: (a -> b) -> (c -> d) -> (a,c) -> (b,d)
(.*.) f g (a,c) = (f a, g c)
instance Arrow SF where
arr f = SF (map f)
first (SF f) = SF (uncurry zip . (f .*. id) . unzip)
instance ArrowLoop SF where
loop (SF f) = SF $ \as -> let (bs,cs) = unzip (f (zip as (stream cs))) in bs
where stream ~(x:xs) = x:stream xs
instance ArrowChoice SF where
left (SF f) = SF (\xs -> combine xs (f [y | Left y <- xs]))
where combine (Left y: xs) (z:zs) = Left z : combine xs zs
combine (Right y :xs) zs = Right y : combine xs zs
combine [] zs = []
instance ArrowCircuit SF where
delay x = SF (x:)
and then
mapA :: ArrowChoice arr => arr a b -> arr [a] [b]
listcase [] = Left ()
listcase (x:xs) = Right (x,xs)
mapA f = arr listcase >>>
arr (const []) ||| (f *** mapA f >>> arr (uncurry (:)))
What I cannot understand is that
> runSF (mapA (delay 0)) [[1,2,3],[4,5],[6],[7,8],[9,10,11],[12,13,14,15]]
[[0,0,0],[1,2],[4],[6,5],[7,8,3],[9,10,11,0]]
I thought that the result should be just adding a 0
at the head of each list since delay 0
is defined as SF (0:)
.
And even more strange,
diag :: (ArrowCircuit a , ArrowChoice a) => a [b] [b]
diag = arr listcase >>>
arr (const []) ||| (arr id *** (diag >>> delay []) >>> arr (uncurry (:)))
runSF diag [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
[[1],[4,2],[7,5,3],[10,8,6]]
I can see what are diag
and mapA (delay 0)
doing, but I cannot quite understand the computation process with using delay
. Can someone just help? Thanks.