Well, the evident solution would be the following:
class Builder b where
type Element b
build :: Element b -> b
instance Builder B.Builder where
type Element B.Builder = Int8
build = B.int8
instance Builder T.Builder where
type Element T.Builder = Int8
build = T.decimal
However the problem with this is that type families can't be used to determine the instance. So in this case the instance can only be determined by the b
from build :: Element b -> b
, but not by the Element b
. This is useful to know, when dealing with typechecker errors.
Due to what I've just mentioned in many cases only data families can be used. The standard approach is to provide a newtype wrapper. E.g.:
class Builder b where
data Element b
build :: Element b -> b
instance Builder B.Builder where
newtype Element B.Builder = BElement Int8
build (BElement a) = B.int8 a
In this case the instance can be determined from both the b
and the Element b
of build :: Element b -> b
.