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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe