Dynamic dispatch, smart constructors, Template Haskell perhaps?

333 views Asked by At

I'm looking at HaskellWiki > Existential type # Dynamic dispatch mechanism.

And I'm thinking, there should be a way in Template Haskell to take this part:

class Shape_ a where
    ...

type Radius = Double
data Circle = Circle Radius

instance Shape_ Circle where
    ...

and automatically derive this part:

-- derive the data type
data Shape = forall a. Shape_ a => Shape a

-- derive smart constructors similar to the original constructor
circle :: Radius -> Shape
circle r = Shape (Circle r)

Has this been done in Template Haskell? Can this be done in TH? Can something similar be done in plain old Haskell without having to write out all of the smart constructors by hand? Would this require a special pre-processor that is more powerful than TH?

2

There are 2 answers

2
glaebhoerl On BEST ANSWER

It can most definitely be done with Template Haskell. There's very little which can't. But I find writing Template Haskell code to be rather painful.

With GHC 7.4 and the ConstraintKinds extension, you can also abstract part of it:

data Some :: (* -> Constraint) -> * where
    Some :: forall cls a. cls a => a -> Some cls

type Shape = Some Shape_

instance Shape_ Shape where
    perimeter (Some a) = perimeter a
    area (Some a) = area a

shape :: Shape_ a => a -> Shape
shape = Some

Automating those instance declarations is another thing TH, and to the best of my knowledge only TH, can do.

1
Michael Snoyman On

What about adding a method to the Shape_ class with a default implementation:

toShape :: a -> Shape
toShape = Shape

For prior art, see the Exception class and SomeException datatype.