[Haskell-beginners] Custom type classes

Guillaume Bouchard guillaum.bouchard+haskell at gmail.com
Wed Jan 27 09:17:47 UTC 2016


On Wed, Jan 27, 2016 at 9:41 AM, Imants Cekusins <imantc at gmail.com> wrote:
> Thank you Guillaume
>
> fun deps are new for me too.
>
> quoting from the above wiki link:
>
>
> -- Read as: "container" type determines "elem" type.
> class Extract container elem | container -> elem where
>   extract :: container -> elem
> The functional dependency "container -> elem" promises that we won't
> declare multiple instances with the same "container" type.
>
>
>
> Without the functional dependency, both instances above would be
> allowed, and the type of v would be potentially ambiguous. Even if
> only one instance is defined, the type system will not figure it out
> without the functional dependency.

At first this is weird because we have the feeling that  `instance
Indexable (Tuple2 a b) a` fully qualifie the second type "a" as
equivalent to the first subtype "a" of Tuple2. This is True for this
instance, but the typechecker does not try to find one instance which
match, it tries to find if , knowing the class definition, it is
possible to be sure that there will only be one instance matching, and
this is not the case because someone can easily define `instance
Indexable (Tuple2 a b) String`.

That's something I really like about this mecanism, is that adding new
instances later cannot change the behavior of previous one.

[A bit of digression]

Actually, I don't know why, but at first though I always think in the
wrong direction when reasoning about types. FunctionalDependencies is
one example, but I had the same issue when I tried to understand why
`fmap` cannot work on unboxed Vector. When reading the types, `fmap ::
Functor f => (a -> b) -> f a -> f b`, I was understanding that it
accepts any `a` as input. It was working on `Vector a`, but not on
`Unbox a => Vector a` which appears more constrained, so if `fmap` was
accepting any `a` as argument, it will certainly accept an `Unbox a`
which is more constrained. But actually it works the opposite, `fmap`
types means that `a` should be anything, and not something
constrained.


More information about the Beginners mailing list