arrays - Can't find a proper signature for a function using STUArray (neither can GHC) -
i built function finding determinant of matrix using st-monad , unboxed starrays (stuarray). type matrix following:
newtype matrix e = matrix (array int (uarray int e))
that is, immutable array containing immutable unboxed arrays containing elements. require me add predicate iarray uarray e
functions dealing matrix
, in turn requires flexiblecontexts
. okay, done.
the function used calculate determinant has following signature:
detst :: (iarray uarray e, marray (stuarray s) e (st s), num e, eq e, division e) => array int (uarray int e) -> st s e
i required add predicate marray (stuarray s) e (st s)
since internally arrays converted mutable arrays (the outer boxed, inner unboxed).
this function can used so:
main = let m@(matrix x) = matrix [ [1,-2,3,234] , [5,2,3,-3] , [7,18,3,40] , [2,9,71,0] ] d = runst (detst x) :: int -- needed type check, ambiguous otherwise print d
works, fine. how ugly is! of course not want give away internals of of matrix
(at least not further predicates attached functions make me to). define following function:
det :: matrix e -> e
and can't.
i tried without proper signature:
det (matrix arr) = runst (detst arr)
fails. fair enough, i'll put brain work: detst
requires iarray uarray e, marray (stuarray s) e (st s), num e, eq e, division e
, det
, doesn't it?
det :: (iarray uarray e, marray (stuarray s) e (st s), num e, eq e, division e) => matrix e -> e
fails. don't see how. message ghc (7.4.2) gives me is:
could not deduce (marray (stuarray s) t (st s)) arising use of `detst'
but exact term in predicates!
ghc suggests:
add (marray (stuarray s) t (st s)) context of type expected context: st s t or inferred type of det :: (eq t, num t, iarray uarray t, division t) => matrix t -> t or add instance declaration (marray (stuarray s) t (st s))
okay. understanding have done first thing. there exist instance (marray ...)
(otherwise, how have used in main?!).
i not sure wrong here. believe has "hidden" st state in s
, , s of detst
other s
s
in det
be, don't know how write type this.
what proper definition of det
- , why?!
the program without det
compiles fine using flexiblecontexts
, no warnings -wall
. complete source code can found as gist here.
i managed work using trick described keegan mcallister in article:
{-# language flexiblecontexts, scopedtypevariables, rankntypes, gadts #-} data evidence s e evidence :: (marray (stuarray s) e (st s)) => evidence s e data elemtype e = elemtype (forall s. evidence s e) det :: forall e . (iarray uarray e, num e, eq e, division e) => elemtype e -> matrix e -> e det (elemtype e) mat = runst (f e mat) f :: evidence s e -> matrix e -> st s e f evidence (matrix arr) = detst arr
usage:
main :: io () main = let m = matrix [ [1,-2,3,234] , [5,2,3,-3] , [7,18,3,40] , [2,9,71,0] ] print $ det (elemtype evidence) (m :: matrix int)
the problem stems lack of higher-rank constraints - runst
has type (forall s. st s a) -> a
, need constraint forall s . marray (stuarray s) e (st s)
, not supported ghc. trick allows convince type checker constraint holds. more in-depth discussion of problem available in article linked above.
Comments
Post a Comment