haskell - Having ST(U)Arrays in a data structure? -


what have make ghc accept code:

{-# language multiparamtypeclasses, flexibleinstances #-}  module sttest  import data.array.st import control.monad.st.strict s import control.monad.st.lazy l  -- st monad arrays (unboxed in actual code) type arr s = starray s int  -- representing algorithm works on these starrays data arrgen s = arrgen (a -> s.st s (arr s a)) (arr s -> s.st s ())  -- class "generator" class generator g   gen :: g -> -> [a]  instance generator (arrgen s a)   gen (arrgen create apply) s = l.runst $     <- stricttolazyst $ create s -- not work     stricttolazyst $ apply >> getelems 

the error following:

couldn't match type `s' `s1'   `s' rigid type variable bound      instance declaration @ sttest.hs:20:28   `s1' rigid type variable bound      type expected context: l.st s1 [a] @ sttest.hs:21:33 

however, works fine:

data dummy create' :: -> s.st s (arr s a) create' = undefined apply' :: arr s -> s.st s [a] apply' = undefined  instance generator dummy   gen _ s = l.runst $     <- stricttolazyst $ create' s     stricttolazyst $ apply' >> getelems 

why work second , not first? , can data declaration make work? or can add sort of "forall" on instance declaration?

the above minimal test program. loop apply forever create infinite stream of output values. (so can't merge 2 steps together.) , want able instantiate once arrgen data type , make variety of values of using these starray algorithms.

edit:

didn't think put forall inside functions arrgen (i put on overall type). though have problem of getting work on stuarray. if use following:

class (integral a, bits a, forall s. marray (stuarray s) (s.st s)) => hasstu type ac = (hasstu a) => forall s. -> s.st s (stuarray s int a) type au = (hasstu a) => forall s. stuarray s int -> s.st s () type tx = (hasstu a) => -> -- or without context data arraygen = ag (ac a) (au a) (tx a) 

then fails:

instance (hasstu a) => generator (arraygen a) [a]   gens (ag c u p) s = fmap (fmap p) $ l.runst $     ar <- stricttolazyst $ (c s)     streamm $ stricttolazyst $ u ar >> getelems ar -- can't use getelems here!  streamm :: (applicative f) => f -> f (stream a)) streamm = cons <$> <*> streamm 

it complains:

could not deduce (marray (stuarray s) (s.st s))   arising use of `getelems' context (hasstu a) 

even though context (hasstu a) says (in mind) there (marray (stuarray s) (s.st s)) context s, doesn't seem think so. tried fix changing (au a) type:

type au = (hasstu a) => forall s. stuarray s int -> s.st s [a] 

and seems type check, unable use it. if change to:

class (integral a, bits a, forall s. marray (stuarray s) (s.st s)) => hasstu s type ac = (forall s. hasstu s a) => -> s.st s (stuarray s int a) ... instance (forall s. hasstu s a) => generator (arraygen a) [a]   ...  instance forall s. hasstu s word32 -- !!! 

but when try run something:

could not deduce (forall s. hasstu s word32) 

i hate s! why? have instance all s! , lost should put foralls , what's going on.

the problem runst requires forall s. st s t argument, type fixes s, use of create , apply in monadic action makes unsuitable runst.

it not seem me use case forbids giving arrgen polymorphic (in s) arguments, so

{-# language multiparamtypeclasses, flexibleinstances, rankntypes #-}  module sttest  import data.array.st import control.monad.st.strict s import control.monad.st.lazy l  -- st monad arrays (unboxed in actual code) type arr s = starray s int  -- representing algorithm works on these starrays data arrgen = arrgen (forall s. -> s.st s (arr s a)) (forall s. arr s -> s.st s ())  -- class "generator" class generator g   gen :: g -> -> [a]  instance generator (arrgen a)   gen (arrgen create apply) s = l.runst $     <- stricttolazyst $ create s -- not work     stricttolazyst $ apply >> getelems 

making components polymorphic works (at least in sense compiles, use case may forbid approach).

why work second , not first?

because there, s not fixed, computation polymorphic in s, required runst.


Comments