ChrisK wrote:
Could I has one question? What is the purpose of the "stream" function in the ArrowLoop instance? Is it just to catch an unexpected [] at runtime?

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

It looks like stream is (almost) an identity which would crash at runtime if it encountered a []. In particular it is equivalent to

 >      where stream xs = head xs:stream (tail xs)


Not quite that, from a blog post of mine a while back:

[snip]

But then the trouble arrived - I suddenly noticed that the paper was using infinite sequences, not the finite sequences I was using myself. Trying to implement an ArrowLoop as per the paper led to horrible grief:

-- instance ArrowLoop SF where
--  loop (SF f) = SF (loop (unzip . f . uncurry zip))

The problem is that this is far too strict - on non-empty input it caused stack overflow crashes, which isn't exactly what I wanted. I found the solution in Programming With Arrows [1] (page 17), which involves some subtlety with lazy patterns:

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

[unsnip]

http://www.haskell.org/arrows/biblio.html#Hug05 [1]


Hope this helps,


Claude
--
http://claudiusmaximus.goto10.org
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to