Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Haskell's type system to specify that a class obeys extra properties (i.e. type classes for type classes)

Tags:

types

haskell

When we create a type class, we usually assume that its functions must obey some properties. Thus we have the Monoid and Monad laws for their respective type classes. But, what if there is some law, like associativity, that I want to specify that multiple classes either may or may not obey that law? Is there a way to do that in Haskell's type system? Is this sort of type classes for type classes idea even feasible in practice?


Here's a motivating example from algebra:

class Addition x where
    add :: x -> x -> x

class Multiplication x where
    mult :: x -> x -> x

instance Addition Int where
    add = (+)

instance Multiplication Int where
    add = (*)

Now, if I want to specify that addition over Int's is associative and commutative, I can create the classes and instances:

class (Addition x) => AssociativeAddition x where
class (Addition x) => CommutativeAddition x where

instance AssociativeAddition Int where
instance CommutativeAddition Int where

But this is cumbersome because I have to create all possible combinations for all classes. I can't just create Associative and Commutative classes, because what if addition is commutative, but multiplication is not (like in matrices)?

What I would like to be able to do is say something like:

class Associative x where

instance (Associative Addition, Commutative Addition) => Addition Int where
    add = (+)

instance (Commutative Multiplication) => Multiplication Int where
    mult = (*)

Can this be done?

(Haskell's abstract algebra packages, like algebra and constructive-algebra, do not currently do this, so I'm guessing not. But why not?)

like image 924
Mike Izbicki Avatar asked Jul 30 '12 20:07

Mike Izbicki


People also ask

What is it called when the type of a function contains one or more class constraints Haskell?

A polymorphic function is called overloaded if its type contains one or more class constraints. (+) :: Num a ⇒ a -> a -> a. For any numeric type a, (+) takes two values of type a and returns a value of type a.

How do you define Typeclass in Haskell?

What's a typeclass in Haskell? A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.

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 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

You actually can do this with some recent GHC extensions:

{-# LANGUAGE ConstraintKinds, KindSignatures, MultiParamTypeClasses #-}
import GHC.Exts (Constraint)

class Addition (a :: *) where
    plus :: a -> a -> a

instance Addition Integer where
    plus = (+)

class (c a) => Commutative (a :: *) (c :: * -> Constraint) where
    op :: a -> a -> a

instance Commutative Integer Addition where
    op = plus
like image 90
Ptharien's Flame Avatar answered Oct 20 '22 02:10

Ptharien's Flame