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

Am Donnerstag, den 03.12.2009, 01:16 +0100 schrieb Martijn van Steenbergen:
So here's a totally wild idea Sjoerd and I came up with.
What if newtypes were unwrapped implicitly?
What advantages and disadvantages would it have? In what cases would this lead to ambiguous code?
1) instance Monoid a => Monoid (Dual a) 2) instance Monoid (Endo a) instance Monoid b => Monoid (a -> b)

The idea is that there's just enough unwrapping such that you don't need to use getDual and appEndo. On Dec 3, 2009, at 1:25 AM, Holger Siegel wrote:
Am Donnerstag, den 03.12.2009, 01:16 +0100 schrieb Martijn van Steenbergen:
So here's a totally wild idea Sjoerd and I came up with.
What if newtypes were unwrapped implicitly?
What advantages and disadvantages would it have? In what cases would this lead to ambiguous code?
1) instance Monoid a => Monoid (Dual a)
2) instance Monoid (Endo a) instance Monoid b => Monoid (a -> b)
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Sjoerd Visscher sjoerd@w3future.com

Am Donnerstag, den 03.12.2009, 01:40 +0100 schrieb Sjoerd Visscher:
The idea is that there's just enough unwrapping such that you don't need to use getDual and appEndo.
Yes, but what does Dual [1] `mappend Dual [2] mean then? Should it use the Monoid instance of Dual and return Dual [2, 1] ? Should it unwrap the lists beforehand and re-wrap them afterwards and return Dual [1, 2] ? Should it unwrap the resulting list afterwards and return [1, 2] or even [2,1] ? That's not obvious to me.
On Dec 3, 2009, at 1:25 AM, Holger Siegel wrote:
Am Donnerstag, den 03.12.2009, 01:16 +0100 schrieb Martijn van Steenbergen:
So here's a totally wild idea Sjoerd and I came up with.
What if newtypes were unwrapped implicitly?
What advantages and disadvantages would it have? In what cases would this lead to ambiguous code?
1) instance Monoid a => Monoid (Dual a)
2) instance Monoid (Endo a) instance Monoid b => Monoid (a -> b)
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Sjoerd Visscher sjoerd@w3future.com

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). Sjoerd On Dec 3, 2009, at 11:47 AM, Holger Siegel wrote:
Am Donnerstag, den 03.12.2009, 01:40 +0100 schrieb Sjoerd Visscher:
The idea is that there's just enough unwrapping such that you don't need to use getDual and appEndo.
Yes, but what does
Dual [1] `mappend Dual [2]
mean then? Should it use the Monoid instance of Dual and return
Dual [2, 1]
? Should it unwrap the lists beforehand and re-wrap them afterwards and return
Dual [1, 2]
? Should it unwrap the resulting list afterwards and return [1, 2] or even [2,1] ?
That's not obvious to me.
On Dec 3, 2009, at 1:25 AM, Holger Siegel wrote:
Am Donnerstag, den 03.12.2009, 01:16 +0100 schrieb Martijn van Steenbergen:
So here's a totally wild idea Sjoerd and I came up with.
What if newtypes were unwrapped implicitly?
What advantages and disadvantages would it have? In what cases would this lead to ambiguous code?
1) instance Monoid a => Monoid (Dual a)
2) instance Monoid (Endo a) instance Monoid b => Monoid (a -> b)
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Sjoerd Visscher sjoerd@w3future.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Sjoerd Visscher sjoerd@w3future.com

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. Neil.
participants (3)
-
Holger Siegel
-
Neil Brown
-
Sjoerd Visscher