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
Post a Comment