The main question about Haskell monomorphism / polymorphism (HList)

I am Haskell and Stackoverflow noob, and here is my first and probably pretty simple Haskell question.

module M where import Data.HList data R ra r1 = undefined :: R a Int r2 = undefined :: R a Double rPair :: R ra -> R rb -> (R ra, R rb) rPair = (,) rp = rPair r1 r2 

This makes sense, even if r1 and r2 are polymorphic in r. RPair aligns its type r with the signature type. Is there a technical term for this "alignment"?

 class HList l => RList rl instance RList r HNil instance RList rl => RList r (HCons (R ra) l) rCons :: RList rl => R ra -> l -> (HCons (R ra) l) rCons = hCons rc = rCons r1 (rCons r2 hNil) 

rCons works fine if traversed R is monomorphic in r, holding back the list type r as desired. but if they are polymorphic in r, it does not align them like rPair and gives an error (rc definition above).

 No instance for (RList r (HCons (R r1 Double) HNil)) 

I have a vague intuition as to why this is so, but my question has two parts. Can someone clearly explain the phenomenon? How would I write rCons so that the following would be?

 r1 = undefined :: R a Int r2 = undefined :: R a Double rc :: HCons (R a Int) (HCons (R a Double) HNil) rc = rCons r1 (rCons r2 hNil) 

Thanks _c

+4
source share
1 answer

To answer the second question, you can use the type equivalence constraint (from the TypeFamilies extension) to relax the definition of an RList instance:

 class HList l => RList rl instance RList r HNil instance (RList r1 l, r1 ~ r2) => RList r1 (HCons (R r2 a) l) 

Now your rc will be deduced on the necessary type.

I don’t think I can “clearly explain” the phenomenon, although (someone will probably be), but it’s obvious that the difference between rPair and rCons is that although the first binds the type r both arguments to the same type variable, this is not so further: the second argument is just l limited so that RList must be some instance of RList for this RList ). Since there is no type signature for rc (note that if you specify one of your original typechecks examples), and r1 and r2 are polymorphic and not equivalent, r , the compiler tries to find an instance definition for RList r (HCons (R r1 Double) HNil) ( r comes from the 1st argument, and r1 from the second) and cannot do this. With the restriction of type equivalence, we define an instance of RList with two different r1 and r2 with the only condition that they must be equivalent, so it seems that GHC binds them to the same variable of polymorphic type when resolving an instance of RList for l .

+1
source

Source: https://habr.com/ru/post/1342375/


All Articles