
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

I think you might want -XGeneralizedNewtypeDeriving http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id659906 On 08/09/10 22:01, Kevin Jardine wrote:
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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Tony Morris http://tmorris.net/

Hi Tony,
I stared at that specific section for at least half an hour earlier
today but could not figure out how it applied in my specific case. The
only examples I have see are for deriving Num. Do you have any more
detail on how I could use that extension?
Kevin
On Sep 8, 2:05 pm, Tony Morris
I think you might want -XGeneralizedNewtypeDeriving
http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id6...
On 08/09/10 22:01, Kevin Jardine wrote:
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 _______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Tony Morrishttp://tmorris.net/
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

On 08/09/10 22:19, Kevin Jardine wrote:
Hi Tony,
I stared at that specific section for at least half an hour earlier today but could not figure out how it applied in my specific case. The only examples I have see are for deriving Num. Do you have any more detail on how I could use that extension?
Here is an example: {-# LANGUAGE GeneralizedNewtypeDeriving #-} class C a where c :: a -> Int data G = G instance C G where c _ = 7 newtype H = H G deriving C -- Tony Morris http://tmorris.net/

On Sep 8, 2010, at 8:19 AM, Kevin Jardine wrote:
Hi Tony,
I stared at that specific section for at least half an hour earlier today but could not figure out how it applied in my specific case. The only examples I have see are for deriving Num. Do you have any more detail on how I could use that extension?
Kevin
On Sep 8, 2:05 pm, Tony Morris
wrote: I think you might want -XGeneralizedNewtypeDeriving
http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id6...
On 08/09/10 22:01, Kevin Jardine wrote:
I'm not sure if it's what he originally had in mind, but if your Obj class has a ToObj instance (which would be reasonable), then that extension allows your other classes to derive it:
newtype Foo = Foo Obj deriving ToObj
-- James

Hi Tony and James,
I'm having trouble constructing the ToObj instance.
The obvious code:
toObj (w o) = o
fails with a syntax error.
How do I unwrap the value?
Kevin
On Sep 8, 2:30 pm, James Andrew Cook
On Sep 8, 2010, at 8:19 AM, Kevin Jardine wrote:
Hi Tony,
I stared at that specific section for at least half an hour earlier today but could not figure out how it applied in my specific case. The only examples I have see are for deriving Num. Do you have any more detail on how I could use that extension?
Kevin
On Sep 8, 2:05 pm, Tony Morris
wrote: I think you might want -XGeneralizedNewtypeDeriving
http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id6...
On 08/09/10 22:01, Kevin Jardine wrote:
I'm not sure if it's what he originally had in mind, but if your Obj class has a ToObj instance (which would be reasonable), then that extension allows your other classes to derive it:
newtype Foo = Foo Obj deriving ToObj
-- James_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

Ah, I was missing an important piece of the puzzle.
If I write:
class ToObj a where
toObj :: a -> Obj
instance ToObj Obj where
toObj a = a
then
newtype Blog = Blog Obj deriving ToObj
works!
Thanks.
On Sep 8, 2:36 pm, Kevin Jardine
Hi Tony and James,
I'm having trouble constructing the ToObj instance.
The obvious code:
toObj (w o) = o
fails with a syntax error.
How do I unwrap the value?
Kevin
On Sep 8, 2:30 pm, James Andrew Cook
wrote: On Sep 8, 2010, at 8:19 AM, Kevin Jardine wrote:
Hi Tony,
I stared at that specific section for at least half an hour earlier today but could not figure out how it applied in my specific case. The only examples I have see are for deriving Num. Do you have any more detail on how I could use that extension?
Kevin
On Sep 8, 2:05 pm, Tony Morris
wrote: I think you might want -XGeneralizedNewtypeDeriving
http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id6...
On 08/09/10 22:01, Kevin Jardine wrote:
I'm not sure if it's what he originally had in mind, but if your Obj class has a ToObj instance (which would be reasonable), then that extension allows your other classes to derive it:
newtype Foo = Foo Obj deriving ToObj
-- James_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

On Wed, 8 Sep 2010 05:51:22 -0700 (PDT), Kevin Jardine
Ah, I was missing an important piece of the puzzle.
If I write:
class ToObj a where toObj :: a -> Obj
instance ToObj Obj where toObj a = a
then
newtype Blog = Blog Obj deriving ToObj
works!
This post http://www.haskell.org/pipermail/libraries/2006-October/005950.html describes a general mini-library for this situation (having a structure-indicating newtype of an underlying type). The 'Unpack' class is a generalised version of your 'ToObj' class. Maybe it is useful to compare (or even use), especially the smart ways in which you can use this class to hide much of the wrapping/unwrapping. Regards, Arie

Thanks Arie,
I'm going to make some of my bare Obj functions accept a ToObj
typeclass constraint and do the conversions inside there to avoid
cluttering up the wrapped object code.
Now that I know how to do this I'm going to see what more
restructuring I can do to make the difference between wrapped and bare
objects less visible (except of course where it should matter).
Kevin
On Sep 8, 3:44 pm, Arie Peterson
On Wed, 8 Sep 2010 05:51:22 -0700 (PDT), Kevin Jardine
wrote: Ah, I was missing an important piece of the puzzle.
If I write:
class ToObj a where toObj :: a -> Obj
instance ToObj Obj where toObj a = a
then
newtype Blog = Blog Obj deriving ToObj
works!
This post http://www.haskell.org/pipermail/libraries/2006-October/005950.html describes a general mini-library for this situation (having a structure-indicating newtype of an underlying type). The 'Unpack' class is a generalised version of your 'ToObj' class. Maybe it is useful to compare (or even use), especially the smart ways in which you can use this class to hide much of the wrapping/unwrapping.
Regards,
Arie
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

Here's a different approach: If you just want to make the typechecker distinguish between some values but still have some functions that don't care what "subtype" they are, you can use phantom types: data Obj x = Obj X Y Z data BlogObj type Blog = Obj BlogObj data CommentObj type Comment = Obj CommentObj data UserObj type User = Obj UserObj Now you can write a function that takes a Blog, and it will refuse other kinds of 'Obj'. But you can still write a function that takes 'Obj x' and it will accept any kind of Obj. So you don't need to do any unwrapping if you leave the functions that matter polymorphic.

Kevin Jardine
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.
Simple solution: data ObjContent = Blah data Obj = Blog { getObj :: !ObjContent } | Comment { getObj :: !ObjContent } | User { getObj :: !ObjContent } With your GetObject class this even becomes extensible: instance GetObject Obj where getObject = getObj data OtherType = OtherType ObjContent instance GetObject OtherType where getObject (OtherType obj) = obj
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.
But it's not what you are looking for. You are confusing constructor types with type kinds. Foldable expects a type of kind * -> *, which isn't quite what you want. Also I would consider this to be abuse. Also from a complexity standpoint it's nothing different from your GetObject class anyway. You still need to write the instances. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

Hi Ertugrul,
My goal was to find a way to define all that was needed using
Haskell's automatic instance deriving mechanism. Haskell can
automatically derive Foldable, which is why I was looking at that.
However, that requires writing two lines for each wrapper newtype to
get around the kind problem.
I wanted one line.
Fortunately,
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
gives me what I want now that I know how it works!
I agree that the Foldable solution was a bit of a kludge.
Kevin
On Sep 9, 3:57 am, Ertugrul Soeylemez
Kevin Jardine
wrote: 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.
Simple solution:
data ObjContent = Blah
data Obj = Blog { getObj :: !ObjContent } | Comment { getObj :: !ObjContent } | User { getObj :: !ObjContent }
With your GetObject class this even becomes extensible:
instance GetObject Obj where getObject = getObj
data OtherType = OtherType ObjContent
instance GetObject OtherType where getObject (OtherType obj) = obj
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.
But it's not what you are looking for. You are confusing constructor types with type kinds. Foldable expects a type of kind * -> *, which isn't quite what you want. Also I would consider this to be abuse. Also from a complexity standpoint it's nothing different from your GetObject class anyway. You still need to write the instances.
Greets, Ertugrul
-- nightmare = unsafePerformIO (getWrongWife >>= sex)http://ertes.de/
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe

Kevin Jardine
My goal was to find a way to define all that was needed using Haskell's automatic instance deriving mechanism. Haskell can automatically derive Foldable, which is why I was looking at that.
However, that requires writing two lines for each wrapper newtype to get around the kind problem.
I wanted one line.
There: newtype Blog = Blog { getBlogObj :: Obj } newtype Comment = Comment { getCommentObj :: Obj } newtype User = User { getUserObj :: Obj } class GetObject a where getObject :: a -> Obj instance GetObject Blog where getObject = getBlogObject instance GetObject Comment where getObject = getCommentObject instance GetObject User where getObject = getUserObject You shouldn't abuse Foldable for this purpose, unless you really mean it.
I agree that the Foldable solution was a bit of a kludge.
And not necessary either. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

Hi Ertugrul,
if you look back earlier in this thread, you'll see that
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
allows me to write genuine one line definitions for each wrapper type.
Eg.
newtype Blog = Blog Obj deriving ToObj
There is no need to code the instances as GHC will do that for you.
Figuring out how to avoid writing the instances was the point of my
original post.
Kevin
On Sep 9, 11:10 am, Ertugrul Soeylemez
Kevin Jardine
wrote: My goal was to find a way to define all that was needed using Haskell's automatic instance deriving mechanism. Haskell can automatically derive Foldable, which is why I was looking at that.
However, that requires writing two lines for each wrapper newtype to get around the kind problem.
I wanted one line.
There:
newtype Blog = Blog { getBlogObj :: Obj } newtype Comment = Comment { getCommentObj :: Obj } newtype User = User { getUserObj :: Obj }
class GetObject a where getObject :: a -> Obj instance GetObject Blog where getObject = getBlogObject instance GetObject Comment where getObject = getCommentObject instance GetObject User where getObject = getUserObject
You shouldn't abuse Foldable for this purpose, unless you really mean it.
I agree that the Foldable solution was a bit of a kludge.
And not necessary either.
Greets, Ertugrul
-- nightmare = unsafePerformIO (getWrongWife >>= sex)http://ertes.de/
_______________________________________________ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
participants (6)
-
Arie Peterson
-
Ertugrul Soeylemez
-
Evan Laforge
-
James Andrew Cook
-
Kevin Jardine
-
Tony Morris