[Haskell-cafe] Re: Aren't type system extensions fun? [Further analysis]

Isaac Dupree isaacdupree at charter.net
Tue May 27 17:43:05 EDT 2008

Chaddaï Fouché wrote:
>> - Why are top-level variables and function arguments treated differently by
>> the type system?
> They aren't

In a sense, they are.

id :: (forall a. a -> a)
useId :: (forall a. a -> a) -> (Int,Bool)
brokenUseId :: (forall a. (a -> a) -> (Int,Bool))
brokenUseId :: (a -> a) -> (Int,Bool)

Note that polymorphic variables in function argument types scope over 
the function results too by default.  And that's a good thing.  Otherwise,
id :: a -> a
would be understood as
brokenId :: (forall a. a) -> (forall a. a)
which is not at all intended ("id" specialized to _|_ values only). 
Basically, you only want higher-rank types in Haskell when you know what 
you're doing: due to parametric polymorphism it is less often useful to 
apply an argument function to, e.g., both Int and Bool than you might 
find in Python, for example.  In Haskell, more often you would just take 
two functions as arguments e.g.
useFunctions :: (Int -> Int) -> (Bool -> Bool) -> (Int,Bool)
or more interestingly, let's make the caller be able to choose any kind 
of number:
useFunctions2 :: (Num a) => (a -> a) -> (Bool -> Bool) -> (a,Bool)
useFunctions2 :: forall a. (Num a) => (a -> a) -> (Bool -> Bool) -> (a,Bool)


More information about the Haskell-Cafe mailing list