Saturday 15 August 2015

haskell - How can I make a typeclass to represent containers containing extractable `Num` instance types? -



haskell - How can I make a typeclass to represent containers containing extractable `Num` instance types? -

i've been struggling expressing pattern in haskell's type scheme time now. having hard time explaining (i guess don't understand problem plenty formulate it), here goes! (and in advance intrepid adventurers can create sense of , reply question!)

let's pretend have 2 different container types, contf , contd, each of adt holding single value of float , double, respectively (they may newtypes in example).

we want write polymorphic function works on either type. maybe extracts value , adds 1 (so have num constraint). create typeclass, cont, function extracting value.

we cannot have num prototype num :: (num n) => t -> n, because "cannot deduce float ~ n" compile-time errors; introduce associated type family.

{-# language typefamilies #-} info contf = cf float info contd = cd double class cont t type family contnum t :: * num :: t -> contnum t instance cont contf type contnum contf = float num (cf f) = f instance cont contd type contnum contd = double num (cd d) = d contadd1 :: (cont t, num n) => t -> n contadd1 t = num t + 1

however, when seek compile next error.

could not deduce (n ~ contnum t) context (cont t, num n) bound type signature contadd1 :: (cont t, num n) => t -> n

maybe trying inquire is: how create typeclass represent containers containing extractable num instance types? also, note contrived illustration demonstrate hope understand.

the reply in error message. need tell somehow compiler n in fact contnum.

you can do

contadd1:: (cont t, num n, n ~ contnum t) => t -> n

or don't utilize n @ all

contadd1 :: (cont t, num (contnum t)) => t -> contnum t

but lastly 1 needs flexiblecontexts extension.

this first part of question, how create compile. reply question how move constraint @ type class level ? add together it. works :-)

{-# language typefamilies, flexiblecontexts #-} info contf = cf float info contd = cd double class num (contnum t) => cont t type family contnum t :: * num :: t -> contnum t instance cont contf type contnum contf = float num (cf f) = f instance cont contd type contnum contd = double num (cd d) = d contadd1 :: (cont t) => t -> contnum t contadd1 t = num t + 1 > contadd1 (cf 4) 5.0

haskell typeclass type-families

No comments:

Post a Comment