Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whats the syntax for the coproduct (disjoint union) of types in Haskell?

Tags:

haskell

consider the following

data Point=Point{x::Float,y::Float}
data Shape=Circle{centre::Point,radius::Float}
           |Rectangle {uleft::Point,bRight::Point}

Here the type Shape is a coproduct of two types Circle and Rectangle. I may want to reuse the types Circle and Rectangle elsewhere. So it would be useful to do this instead:

data Point=Point{x::Float,y::Float}
data Circle=Circle{centre::Point,radius::Float}
data Rectangle=Rectangle {uleft::Point,bRight::Point}
data Shape =Circle | Rectangle

but I get a compilation error when I do this: Circle is declared twice. Whats the correct syntax for attempting this, or this not possible?

like image 849
Mozibur Ullah Avatar asked Jan 09 '13 22:01

Mozibur Ullah


1 Answers

The coproduct of types in Haskell is commonly denoted by Either:

data Either a b = Left a | Right b

type Shape = Either Circle Rectangle
-- so you have shapes as either Left c for some Circle c
-- or Right r for some Rectangle r

This works quite nicely, although for technical reasons it isn't exactly a coproduct. Another common way would be to define a type like so:

data Shape = CircleShape Circle | RectangleShape Rectangle

so that CircleShape :: Circle -> Shape and RectangleShape :: Rectangle -> Shape are your two injections.

It's wrong to say as you do in your question that the original Shape is a coproduct of types Circle and Rectangle, because the latter two aren't types. If you want to set things up so that Circle p r is both a value of type Circle and a value of type Shape, then that's really contrary to the spirit of Haskell's type system (although something similar might be possible with sufficiently many type system extensions).

like image 166
Ben Millwood Avatar answered Sep 23 '22 06:09

Ben Millwood