Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type parameters constraints for instances of typeclasses with kind * -> *

Suppose I have Heap a type where Heap is type constructor of kind * -> *. Many basic operations on heap require the a type to be an instance of Ord type class.

data Heap a = ...

findMin :: Ord a => Heap a -> a
deleteMin :: Ord a => Heap a -> Heap a

I want to declare my Heap type as an instance of Foldable type class as soon as a type parameter is an instance of Ord type class (it will be easy to express via findMin and deleteMin functions).

This kind of relation can be easely expressed when we dealing with type classes that require type of kind *, like Show:

instance Show a => Show (Heap a) where
    show h = ...

But I have problems with declaration of Foldable:

instance Foldable Heap where
    -- Ouch, there is no `a` type parameter to put the constraint on!
    foldr f z h = ...

Is it possible to put constraint on a type parameter in such instance declaration?

like image 610
roman-kashitsyn Avatar asked Sep 19 '12 15:09

roman-kashitsyn


People also ask

What is a type constraint Haskell?

In Haskell 98, only functions can have type constraints. The type constraint of a data only refers to the constructors. The designers of Haskell 98 do now think, that it was a bad decision to allow constraints on constructors. GHC as of version 7.2 disallows them by default (turn back on with -XDatatypeContexts ).

Are Typeclasses types?

A typeclass is a sort of interface that defines some behavior. If a type is a part of a typeclass, that means that it supports and implements the behavior the typeclass describes. A lot of people coming from OOP get confused by typeclasses because they think they are like classes in object oriented languages.

What are type classes in Haskell?

Type Classes are a language mechanism in Haskell designed to support general overloading in a principled way. They address each of the concerns raised above. They provide concise types to describe overloaded functions, so there is no expo- nential blow-up in the number of versions of an overloaded function.

What is a class instance in Haskell?

An instance of a class is an individual object which belongs to that class. In Haskell, the class system is (roughly speaking) a way to group similar types. (This is the reason we call them "type classes"). An instance of a class is an individual type which belongs to that class.


1 Answers

In general, no, when the type constructor itself is given the instance, there's no way to constrain the types it's applied to. Mostly this is a good thing, since it ensures that e.g. Functor instances are truly agnostic about their element type, which helps keep nice and predictable behavior nice and predictable.

Sometimes it's an annoyance instead, and the most common example is indeed needing an Ord constraint for a sorted data structure that could otherwise be a nice, well-behaved instance.

There are some experimental techniques involving stuff like constraint kinds, but in your specific case there's already a viable solution. If you look at the definition of Foldable, it says that only foldMap or foldr need to be implemented, so we'll consider those. Note the types:

foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
foldr :: (Foldable t) => (a -> b -> b) -> b -> t a -> b

In both cases, the type with a Foldable instance only appears once, as an argument to the function. Because of this, you can use GADTs with an Ord constraint:

data Heap a where
    Heap :: (Ord a) => ...

By doing this, you'll need an Ord instance any time you create a Heap value, even an empty heap; but when you receive a Heap value, pattern matching on it will bring the Ord instance back into scope--even inside the Foldable instance!

Note that this doesn't help in many other situations:

fmap :: (Functor f) => (a -> b) -> f a -> f b

Here we can get an Ord instance on a, but we'd also need one for b, which isn't possible.

return :: (Monad m) => a -> m a

Here we need to provide an Ord instance as well.

like image 147
C. A. McCann Avatar answered Sep 23 '22 23:09

C. A. McCann