[Haskell-cafe] difference between type and newtype

Brian Hulley brianh at metamilk.com
Sat Aug 26 06:55:34 EDT 2006


Andrea Rossato wrote:
> Il Sat, Aug 26, 2006 at 01:27:38AM +0200, Daniel Fischer ebbe a
> scrivere:
>> Because T a is a function type, namely Int -> (a,Int), so
> ...
>
>> iHowever, neither T1 a nor T2 a is a function type, a value of type
>> T1 a is a function _wrapped by the data (or value) constructor T1_
>> (the same applies to T2, of course), so before you can apply mkT1 a
>> to an Int, you have to unwrap it:
>
> so, if I understand correctly,  mkT is just a partial application
> *becase* of its "fake" type signature...

Yes that's right.

>
> that's a bit confusing...
> also because that "type" cannot be instance of a class.
> moreover why it is possible to declare something like this?
> data T2 a = T2 (Int -> (a,Int))
>
> is there any usefulness?

Yes, it's useful because it allows you to make a distinction between 
different uses of the same type of function and make these different uses 
into instances of different classes. It also allows you to hide the fact 
that a function is being used. Such decls are often used in monadic 
programming, for example if you look at the library docs for 
Control.Monad.State you will see the following decl:

    newtype State s a = State {runState :: (s -> (a,s))}
ie
    newtype State s a = State (s -> (a,s))

> I hoped it could work as with types declared with "type".

You probably know this but just in case, a newtype decl gives you the same 
advantages as a "type" decl in terms of speed, since there is no runtime 
overhead, but it also gives you the same advantages as a data decl in terms 
of enforcing distinctions between things that have the same form but 
different meaning in your program.

>
> perhaps this is silly, but it is not possible to declare function
> types?

Consider:

        type T a = a -> Int

        data D a = D (a -> Int)

        newtype N a = N (a -> Int)

In the "type" decl, you've simply made (T a) synonym for (a -> Int) so both 
type expressions are treated as identical by the compiler.

With the "data" decl, you've introduced a new type of entity, (D a), which 
needs to be explicitly unwrapped (ie by pattern matching against (D fun)) to 
access the function. This allows you to make values of type (D a) an 
instance of a class and enforce a distinction between this particular use of 
functions from (a) to Int, without worrying that some other part of the 
program is going to mess everything up. But there is also a runtime penalty 
to pay because of the indirection through the D constructor.

However with the "newtype" decl, you get the best of both worlds - no 
runtime cost but still allowing you to enforce the fact that the entity (N 
a) can't be confused with anything else in your program.

>
> could you please indicate me some documentation that explains this
> kind of stuff? So far I didn't find anything on that.

I recommend chapter 8 of "Yet another Haskell Tutorial" which can be 
downloaded from 
http://www.haskell.org/haskellwiki/Books_and_tutorials#.E2.80.9CReal_world.E2.80.9D_tutorials

If you still need more detail there's always section 4.2 of the Haskell98 
report at http://haskell.org/onlinereport/decls.html which includes an 
example illustrating the subtle difference between newtype and data decls 
that is glossed over in 8.2 of YAHT (warning: may cause sleepless nights but 
definitely worth the effort ;-) )

Regards, Brian.
-- 
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 



More information about the Haskell-Cafe mailing list