[Fwd: Re: [Haskell-cafe] Implicit newtype unwrapping]

Neil Brown nccb2 at kent.ac.uk
Thu Dec 3 06:03:44 EST 2009

Sjoerd Visscher wrote:
> In the case of Dual [1] `mappend` Dual [2] there's no need to do any unwrapping. There is if you say:
> l :: [Int]
> l = Dual [1] `mappend` Dual [2]
> The way I think this could work is that when the type checker detects a type error, it will first try to resolve it by newtype unwrapping (or wrapping even).
So if I have:

l :: Dual [Int]
l = [1] `mappend` [2]

It will wrap after the mappend, rather than before?  But:

l :: Dual [Int]
l = Dual [1] `mappend` [2]

Would wrap the RHS in Dual?  Does this version unwrap the LHS:

l :: [Int]
l = Dual [1] `mappend` [2]

And finally, what about:

l :: [Int]
l = Dual [1] `mappend` Endo [2]

Automatic wrapping and unwrapping, like automatic coercions, look like 
an opportunity for surprising behaviour.  OTOH, perhaps some sort of 
deriving mechanism would be good.  To revisit someone's previous 
suggestion, perhaps you could allow functions in the deriving clause, so 
that if you have:

f :: Foo -> Foo -> Foo

newtype MyFoo = MyFoo {getFoo :: Foo}
  deriving (f as g)

will generate:

g :: MyFoo -> MyFoo -> MyFoo
g x y = Foo (f (getFoo x) (getFoo y))

I think it's not something worth adding (too subtle), but I thought I'd 
throw it in as a possibility.


More information about the Haskell-Cafe mailing list