Newtype wrappers

Ian Lynagh ian at
Tue Jan 15 00:42:52 CET 2013

On Mon, Jan 14, 2013 at 03:28:15PM -0800, Johan Tibell wrote:
> On Mon, Jan 14, 2013 at 3:18 PM, Evan Laforge <qdunkan at> wrote:
> > I assume it would change from "doesn't compile" to "works" if you add
> > the required import.  It's the same as the FFI thing, right?  If you
> > don't import M (T(..)), then 'foreign ... :: T -> IO ()' gives an
> > error, but import it and coerces T to its underlying type (hopefully
> > that's a C type).
> This is what I thought Simon meant. If so, I don't think it's a good
> idea, as adding the import removes a compiler error in favor of a
> runtime error. If the programmer really wanted to do something this
> unsafe, she should use unsafeCoerce.

Simon's proposal would mean that

    import Data.Set.Internal

    newtype wrap w :: Set Int -> Set Age

would be possible, in the same way that

    import Data.Set.Internal

    w :: Set Int -> Set Age
    w (BinSet x y) = BinSet (MkAge x) (MkAge y)
    w Empty = Empty

would be possible. i.e. it wouldn't let you write anything that you
couldn't write anyway (although it would make it easier to write, and
it would have better performance).

The "adding an import makes it compile" issue is a red herring IMO.
Adding the import also makes my second example work for the same reason;
it's just more obvious that the constructor is needed in the second
example as it's visible in the code.


More information about the Glasgow-haskell-users mailing list