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