Определенно это можно сделать с помощью шаблона Haskell. Там очень мало чего не может. Но я нахожу написание кода Template Haskell довольно болезненным.
С GHC 7.4 и расширением ConstraintKinds вы также можете абстрагировать его часть:
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
Автоматизация этих объявлений экземпляров - это еще одна вещь, которую TH, и, насколько мне известно, может сделать только TH.