[Haskell-cafe] Re: variadic functions and typeCast

oleg at pobox.com oleg at pobox.com
Wed Sep 27 21:04:19 EDT 2006

Michael Shulman wrote:
> class TypeCast x y | x -> y, y -> x where
>     typeCast :: x -> y
> instance TypeCast x x where
>     typeCast = id
> Anyway, my main question about typeCast is this: why is it needed here
> at all?

First of all, there is a version of TypeCast that works within the
same module, please see any code described in

Appendix D of the full HList paper (or, HList technical report, I
should say) gives the reasons for TypeCast. 

Briefly, TypeCast lets us replace a (ground) type T with a type
variable "t" subject to the constraint: "TypeCast t T => t".  The
difference seems superficial since the typechecker can immediately
discharge the constraint and replace "t" with "T". Well, placing the
TypeCast declaration in a different module, or the more convenient
magic 6-line declaration of class TypeCast make sure that the
typechecker delays the discharging of the "TypeCast" constraint.  So
the type variable "t" stays uninstantiated for a while. It matters in
instance declarations. For example,

	class Foo x where foo :: x -> Int
	instance Foo [Int]
	instance Foo Bool where foo x = fromEnum x

If we write
	test1 = foo [read "1"]
we get an error: No instance for (Foo [a]). Indeed, `read "1"' has the
type 'a', which does not match "Int". The typechecker certainly cannot
chose the "Foo [Int]" instance because who knows what other instances
of Foo may occur in other modules. We can tell the typechecker however
that "Foo [Int]" is the only instance that can ever be in the whole
program (that is, the world is `locally' closed, as far as the Foo [a]
is concerned). We do that by writing

	instance TypeCast x Int => Foo [x] where foo [x] = typeCast x
and now
	test1 = foo [read "1"]
typechecks (and works), without any type annotations. 

BTW, if we lied and did write another instance for "Foo [T]" for some T,
the typecheker will complain.

More information about the Haskell-Cafe mailing list