[Haskell-cafe] Unwrapping newtypes
Kevin Jardine
kevinjardine at gmail.com
Wed Sep 8 08:01:55 EDT 2010
I have a generic object that I want to wrap in various newtypes to
better facilitate type checking.
For example,
newtype Blog = Blog Obj
newtype Comment = Comment Obj
newtype User = User Obj
Unlike Obj itself, whose internal structure is hidden in a library
module, the newtype wrappings are purely to facilitate type checking.
It is no secret that each is just a wrapper around Obj.
It is obvious how to construct the various wrapper objects. It is not
so obvious how to extract the Obj they contain in a reasonably generic
way however. What I want is a getObj function that works on all of
them.
Of course this could work if someone using the library wrote an
instance for each wrapper object:
instance GetObject Blog where
getObj (Blog obj) = obj
but this is a pain in the neck to write for each newtype.
I discovered that Foldable defines a handy toList function that
extracts content from generic Foldable structures.
So that I could write:
toObj :: Foldable thing => thing Obj -> Obj
toObj w = head $ toList w
Slightly kludgy but it works.
Even better, recent versions of GHC will allow you to automatically
derive Foldable.
Unfortunately,
newtype Blog = Blog Obj deriving Foldable
returns a kind error.
What does work is:
newtype BlogF a = Blog a deriving Foldable
type Blog = BlogF Obj
After having spent close to a day on this, I am a bit baffled that
such a seemingly trivial problem seems so hard to do.
I am wondering if I am missing something really, really obvious.
Any suggestions? Or is there perhaps a more Haskelly way to place type
constraints on a more generic type?
Kevin
More information about the Haskell-Cafe
mailing list