
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" I've been poring over http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types for the last hour and I feel like my eyes are starting to melt. As usual, any input would be warmly received :) All the best, Philip

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@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On 05/29/10 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"
The function must be type-correctly defined for "any a in Show". (the caller/user "chooses" which type "a" is desired.)
but if I use forall in an type qualifier in an assignment:
myList = [] :: [forall a.(Show a) => a]
Each element of this list must be "any a in Show". (the caller/user "chooses" which type "a" is desired.) In this case, the only way to generate a value that is truly "any a in Show" is "undefined".* *some classes, like Read, might provide another possible value, as in [read "123"] which could be [forall a.(Read a) => a] -- albeit only a few types "a", such as Integer and Double, would actually have non-bottom values in this case, but it's easy to construct less-awful examples. Why were you poring over Existentially Quantified Types? -- you didn't use any existentials above -- did you want to? (or I should ask -- can you tell, yet, whether you wanted to?) -Isaac

Philip Scott wrote:
I've been poring over
http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types
for the last hour and I feel like my eyes are starting to melt.
http://en.wikibooks.org/wiki/Haskell/Polymorphism is also relevant. Regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com
participants (4)
-
Brandon S. Allbery KF8NH
-
Heinrich Apfelmus
-
Isaac Dupree
-
Philip Scott