[Haskell-cafe] type inference and named fields

Malcolm Wallace Malcolm.Wallace at cs.york.ac.uk
Fri Jun 24 04:50:41 EDT 2005

Lennart Augustsson <lennart at augustsson.net> writes:

> A somewhat similar problem exists even without fields:
> foo :: Either a b -> Either () b
> foo (Left _) = Left ()
> foo x@(Right _) = x

Your example is less surprising than mine with fields.  The expression
on the rhs of the last clause has type
    Either a b
This does not match the signature, which claims
    Either () b
So it is fairly easy to explain why this is rejected.  Even if we change
the definition of the Either type to omit the Left constructor (and
correspondingly omit the first clause of foo's definition), you still
get an error.

Whereas in the named field example, the rhs expression
    v {field1=Void}
does indeed have the type
    Fields Void
as declared in the signature.  The expression explicitly converts all
the relevant interior fields to Void.  At least, that is how it could
appear to a naive programmer like me :-)  After all, if I change the
definition of the type Fields to omit the constructor VariantWithTwo
(and correspondingly omit the first clause of voidcast's definition),
then suddenly and miraculously, the second clause passes the type
checker.  It is a bit weird that adding a new constructor to a datatype
can cause existing code to fail to typecheck!


> data Fields a =
>     VariantWithTwo { field1 :: a
>                    , field2 :: a }
>   | VariantWithOne { field1 :: a }
> data Void = Void

> voidcast :: Fields a -> Fields Void
> voidcast v@(VariantWithTwo{}) = v { field1 = Void , field2 = Void }
> voidcast v@(VariantWithOne{}) = v { field1 = Void }

More information about the Haskell-Cafe mailing list