[Haskell-beginners] forall confusion
Brandon S. Allbery KF8NH
allbery at ece.cmu.edu
Sat May 29 14:43:39 EDT 2010
On May 29, 2010, at 11:35 , Philip Scott wrote:
> Hi all,
>
> I was wondering if someone could give me an intuitive explanation of
> why in
>
> f :: forall a.(Show a) => a -> String
> f x = show x
>
> "forall a.(Show a) => a" appears to translate into "Any a, as long
> as it is an instance of Show"
>
> but if I use forall in an type qualifier in an assignment:
>
> myList = [] :: [forall a.(Show a) => a]
>
> "forall a.(Show a) => a" seems to mean "Any a, as long as it is
> bottom"
Using the WikiBook's DataBox type as an example:
In the case of [DataBox], I can build list elements with SB (a valid
value for a [Databox] is [SB 1]); what name do I use in place of SB
for the anonymous forall-ed type in myList? Since I don't have such a
name, the only possible value I can use is the one value that exists
in every type: bottom.
Other examples:
f :: forall a. (Show a) => a -> String -- your example above
versus
undefined :: forall a. a -- from the Haskell Prelude
This highlights a corner case: "f" gives you a "nickname" to use,
namely the fact that the forall-ed type is an argument. "undefined"
doesn't give you any handle at all, so its only possible value is
bottom.
data ST s a
runST :: (forall s. ST s a) -> a
runST gives you a temporary name for "a", in the form of the returned
value. You don't have a name for the "s", though, as it's hidden
inside the ST type, which doesn't have any constructors. This is used
to hide information: the invocation "runST myFunc initialValue"
invokes myFunc, passing it initialValue and a special container whose
contents are private (the "s"). myFunc can put things into and take
things out of the container, using the functions in Control.Monad.ST,
and having taken a value out it can pass that value to something else
--- but nothing outside of the definition of myFunc can get at the
container. This is mainly useful when you need to hide an impure
manipulation of values: you can do destructive updates of things
inside the container, as long as any given input to myFunc always
produces the same output (referential transparency: it should always
be possible to replace a function call with its result, meaning it
can't depend on external state other than its parameters). A fast
array library can use runST to perform a destructive-update algorithm
when it's faster than the equivalent pure algorithm, provided both
algorithms always produce the same results for the same inputs.
--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery at kf8nh.com
system administrator [openafs,heimdal,too many hats] allbery at ece.cmu.edu
electrical and computer engineering, carnegie mellon university KF8NH
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 195 bytes
Desc: This is a digitally signed message part
Url : http://www.haskell.org/pipermail/beginners/attachments/20100529/3d87e212/PGP.bin
More information about the Beginners
mailing list