haskell - Understanding type constraints -


my particular problem may have existential types i'm not sure won't put in title.

anyways, here's i'm trying do.

have entity type wraps on heterogeneous list of components. then, have hascomponent b typeclass denotes list b has component of type a. here's how i've written it, , classes instances.

data entity c = entity c  data compnode c n = compnode c n data compend = compend  class hascomponent b     getcomponent :: b ->  instance hascomponent (compnode n)     getcomponent (compnode _) =  instance hascomponent n => hascomponent (compnode b n)     getcomponent (compnode _ n) = getcomponent n  instance hascomponent b => hascomponent (entity b)     getcomponent (entity b) = getcomponent b 

there's hascomponent instance entity. that's convenience.

so far, compiles.

now, i'd try out. i've made displaydata a type holds data of type a that's meant displayed. 1 of components. i've made displayer a wrapper around function of type a -> io (). component meant provide way show data.

data displaydata = displaydata data displayer = displayer (a -> io ()) 

now these 2 components should play nicely together. wanted write function display takes entity satisfies constraints , displays it.

this attempt

display :: (hascomponent (displaydata a) c, hascomponent (displayer a) c) => entity c -> io () display e = f     displayer f = getcomponent e :: displayer           displaydata = getcomponent e :: displaydata 

what mean is: "if there exists type such (hascomponent (displaydata a) c, hascomponent (displayer a) c) true, display can take entity c , produce io action."

what think might mean instead is: "if (hascomponent (displaydata a) c, hascomponent (displayer a) c) true , every type a, display can take entity c , produce io action.

the error this

could not deduce (hascomponent (displaydata a0) c)   arising ambiguity check `display' context (hascomponent (displaydata a) c,                   hascomponent (displayer a) c)   bound type signature              display :: (hascomponent (displaydata a) c,                          hascomponent (displayer a) c) =>                         entity c -> io ()   @ components.hs:24:12-94 type variable `a0' ambiguous in ambiguity check for:   forall c a.   (hascomponent (displaydata a) c, hascomponent (displayer a) c) =>   entity c -> io () defer ambiguity check use sites, enable allowambiguoustypes in type signature `display':   display :: (hascomponent (displaydata a) c,               hascomponent (displayer a) c) =>              entity c -> io () 

how do want here?

first of all, reference type variables in type signature body of function, need enable scopedtypevariables, , add forall type:

{-# language scopedtypevariables #-}  display :: forall c . (hascomponent (displaydata a) c, hascomponent (displayer a) c)          => entity c -> io () display e = f            displayer f = getcomponent e :: displayer       displaydata = getcomponent e :: displaydata 

but still produce error. issue type a mentioned in context, not actual type. there no way compiler ever instantiate type. have several options.

you can add "dummy" parameter contains type:

display :: forall c proxy .               (hascomponent (displaydata a) c, hascomponent (displayer a) c)          => proxy -> entity c -> io () display _ e = f ... 

or, can add functional dependency class, , pragmas:

{-# language overlappinginstances, undecidableinstances #-}  class hascomponent b | b -> 

which says type a determined type b. in case, first form compile.


Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -