ArrowLoop instance example for a data type of type Control.Foldl

I am working on a modification to Control.Foldl that provides Category and Arrow instances. My definition is as follows:

 data FoldlCat ab = forall x c. FoldlCat (x -> a -> c) x (c -> x) (c -> b) 

where the first argument denotes the function "step" ( savedState -> newInput -> intermediateValue ), the second - for the initial savedState , the third - the save function ( intermediateValue -> savedState ), and the last - the function "extract" ( intermediateValue -> newOutput ).

So, something like map (*10) . scanl (+) 0 map (*10) . scanl (+) 0 can be expressed as FoldlCat (+) 0 id (*10) .

The main purpose of the save function is to facilitate the definition of id and arr as follows:

 id = FoldlCat (\_ x -> x) () (const ()) id 

Now I'm trying unsuccessfully to come up with an instance of ArrowLoop . I don’t see the reasons why this is impossible, but it’s not convenient for me with concepts like fix . My best attempt is still typical, but loops forever.

 instance ArrowLoop FoldlCat where loop (FoldlCat sbad) = FoldlCat step b (a . snd) fst where step x = loop' d (sx) loop' fgx = let ~(v, ~(c,d)) = let ~v = g (x,d) in (v, fv) in (c, v) 

I would appreciate it if someone could share their approach in defining such an instance (extra recognition if it works with a strict tuple in the battery inside (.) ) Or explain why this is not possible or advice on the best structure for FoldlCat.

 {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE Arrows #-} import Data.List (unfoldr) import Prelude hiding (id, (.)) import Control.Category import Control.Arrow -- | FoldlCat step init save export data FoldlCat ab = forall x c. FoldlCat (x -> a -> c) x (c -> x) (c -> b) mapCat :: (a -> b) -> FoldlCat ab mapCat f = FoldlCat (\_ x -> x) () (const ()) f evalList :: FoldlCat tb -> [t] -> [b] evalList (FoldlCat sbad) ys = unfoldr stepan (b, ys) where stepan (accVal, (x:xs)) = Just (nexVal, (newAcc, xs)) where newMeta = s accVal x newAcc = a newMeta nexVal = d newMeta stepan (accVal, []) = Nothing delay :: b -> FoldlCat bb delay def = FoldlCat (,) def snd fst instance Category FoldlCat where id = mapCat id (.) (FoldlCat step2 begin2 acc2 done2) (FoldlCat step1 begin1 acc1 done1) = let step = \(a, b) y -> let !a' = step1 ay !b' = step2 b (done1 a') in (a', b') begin = (begin1, begin2) acc = \(x, y) -> ((acc1 x), (acc2 y)) done = \(a, b) -> done2 b in FoldlCat step begin acc done instance Arrow FoldlCat where arr f = mapCat f first (FoldlCat sbad) = FoldlCat step b (a . fst) extF where step = (\a (x, y) -> (sax, y)) extF = (\(ok, y) -> (d ok, y)) instance ArrowLoop FoldlCat where loop (FoldlCat sbad) = FoldlCat step b (a . snd) fst where step x = loop' d (sx) loop' fgx = let ~(v, ~(c,d)) = let ~v = g (x,d) in (v, fv) in (c, v) chaseFromZero = proc target -> do rec let step = signum (target - x) x <- FoldlCat (+) 0 id id <<< delay 0 -< step id -< x main = print $ evalList chaseFromZero [1..5] 

EDIT . Although I'm not sure how and why it works, fixing the strictness of step in (.) (I.e. removing bang in let !a' = step1 ay ) seems to do this example work.

+5
source share

Source: https://habr.com/ru/post/1270852/


All Articles