Tue, 16 May 2000 22:37:45 +0200, Jan Brosius <[EMAIL PROTECTED]> pisze:
> > newSTRef applied to some value can have a type ST s (STRef s T(s)),
>
> That is strange , can you give a little example?
I've given it four mail pairs ago, but here it is again:
refRef :: ST s Int
refRef = do
v1 <- newSTRef 0
v2 <- newSTRef v1 -- Here!
v1' <- readSTRef v2
readSTRef v1'
> (e.g. if there are 2 sorts of type variables in Haskell 2 (or in
> Haskell 98 ) then I would really like to know what is the practical
> reason of this.
I see nothing that could be described as 2 sorts of type variables.
> I don't know if it compiles. If it compiles I can only say that
> this seems strange to me.
> I certainly should not expect that that is possible.
Of course it does not compile in Haskell. This was to show that your
checking "whether something is a type variable" is meaningless: here
a type is a type variable as far as I can tell, but runST requires
some different condition.
> > f1:: (a -> a) -> [Int] -> [Int]
> > f1 f l = map f l
> >
> > This definition does not compile, although f has type a->a.
>
> First I didn't know that the use of forall was obligatory in Haskell 98 .
It is not - and that's why in Haskell 98 you cannot write the
type signature of "f" inside the definition of "f1". If you write
"f:: a -> a", it means "f :: forall a. a -> a", but "f" has a
different type.
In GHC you can write the type of "f", provided that you have given a
name to the type variable in question, using a pattern type signature
or result type signature (the latter not working yet).
> Third If I would give any meaning to forall a. a-> a then I
> would give it the same meaning as a -> a .
Wrong. The first is the type of a function that is polymorphic:
works for any argument type and gives a result of the same type
(there exist only three function of that type in Haskell 98:
bottom, function that always returns bottom, and identity).
The second is the type of a function from "a" to "a". Depending on what
"a" is, it can mean different things. For example if "a" is bound at
some outer function definition, it is the function from the whatever
type the outer function has been instantiated to, to the same type.
> I would like to know why for heaven's sake a distinction has to be
> made between
>
> f1:: ( a -> a) -> [Int] -> [Int]
> and
> f1':: ( forall a . a -> a) -> [Int] -> [Int]
How can you propose a better type of runST if you don't understand
such basic things?!
To use f1, you choose a type for "a", pass a function of the type
"a -> a" and get a function [Int] -> [Int]. For example you can
pass not (of type Bool->Bool) to f1.
To use f1', you must pass a polymorphic function of the type
"forall a. a -> a" to it, and get a function [Int] -> [Int].
You have only three choices for the first function.
To implement f1, you must be prepared for any type for "a" a caller has
chosen. It is hard to use the first argument in an interesting way,
because you have no values of type "a" other than bottom, and there
is little to do with a value of type "a" you get from the function,
because you don't know what "a" will be.
To implement f1', you know that the function is polymorphic, and you
can use it on any type you wish. For example apply it to each element
of the list and then to the list itself.
--
__("< Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/
\__/ GCS/M d- s+:-- a23 C+++$ UL++>++++$ P+++ L++>++++$ E-
^^ W++ N+++ o? K? w(---) O? M- V? PS-- PE++ Y? PGP+ t
QRCZAK 5? X- R tv-- b+>++ DI D- G+ e>++++ h! r--%>++ y-