Newtype wrappers
Iavor Diatchki
iavor.diatchki at gmail.com
Tue Jan 15 03:15:30 CET 2013
Hello,
The general functionality for this seems useful, but we should be careful
exactly what types we allow in the 'newtype wrap/unwrap' declarations. For
example, would we allow something like this:
newtype wrap cvt :: f a -> f (Dual a)
If we just worry about what's in scope, then it should be accepted, however
this function could still be used to break the invariant on `Set` because
it is polymorphic.
In general, I was never comfortable with GHC's choice to add an axiom
equating a newtype and its representation type, because it looks unsound to
me (without any type-functions or newtype deriving).
For example, consider:
newtype T a = MkT Int
Now, if this generates an axiom asserting that `froall a. T a ~ Int`, then
we can derive a contradiction:
T Int ~ Int ~ T Char, and hence `Int ~ Char`.
It looks like what we need is a different concept: one that talks about the
equality of the representations of types, rather then equality of the types
themselves.
-Iavor
On Mon, Jan 14, 2013 at 10:09 AM, Simon Peyton-Jones
<simonpj at microsoft.com>wrote:
> Friends****
>
> ** **
>
> I’d like to propose a way to “promote” newtypes over their enclosing
> type. Here’s the writeup****
>
> http://hackage.haskell.org/trac/ghc/wiki/NewtypeWrappers****
>
> ** **
>
> Any comments? Below is the problem statement, taken from the above page.*
> ***
>
> ** **
>
> I’d appreciate****
>
> **· **A sense of whether you care. Does this matter?****
>
> **· **Improvements to the design I propose****
>
> ** **
>
> Simon****
>
> ** **
>
> ** **
>
> ** **
>
> *The problem*
>
> Suppose we have ****
>
> newtype Age = MkAge Int****
>
> Then if n :: Int, we can convert n to an Age thus: MkAge n :: Age.
> Moreover, this conversion is a type conversion only, and involves no
> runtime instructions whatsoever. This cost model -- that newtypes are free
> -- is important to Haskell programmers, and encourages them to use newtypes
> freely to express type distinctions without introducing runtime overhead.
> ****
>
> Alas, the newtype cost model breaks down when we involve other data
> structures. Suppose we have these declarations ****
>
> data T a = TLeaf a | TNode (Tree a) (Tree a)****
>
> data S m a = SLeaf (m a) | SNode (S m a) (S m a)****
>
> and we have these variables in scope ****
>
> x1 :: [Int]****
>
> x2 :: Char -> Int****
>
> x3 :: T Int****
>
> x4 :: S IO Int****
>
> Can we convert these into the corresponding forms where the Int is
> replaced by Age? Alas, not easily, and certainly not without overhead. ***
> *
>
> - For x1 we can write map MkAge x1 :: [Age]. But this does not follow
> the newtype cost model: there will be runtime overhead from executing the
> map at runtime, and sharing will be lost too. Could GHC optimise the
> map somehow? This is hard; apart from anything else, how would GHC
> know that map was special? And it it gets worse. ****
>
>
> - For x2 we'd have to eta-expand: (\y -> MkAge (x2 y)) :: Char -> Age.
> But this isn't good either, because eta exapansion isn't semantically valid
> (if x2 was bottom, seq could distinguish the two). See #7542<http://hackage.haskell.org/trac/ghc/ticket/7542>for a real life example.
> ****
>
>
> - For x3, we'd have to map over T, thus mapT MkAge x3. But what if mapTdidn't exist? We'd have to make it. And not all data types have maps.
> S is a harder one: you could only map over S-values if m was a
> functor. There's a lot of discussion abou this on #2110<http://hackage.haskell.org/trac/ghc/ticket/2110>.
> ****
>
> ** **
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users at haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/glasgow-haskell-users/attachments/20130114/2611b9d8/attachment-0001.htm>
More information about the Glasgow-haskell-users
mailing list