[Haskell-cafe] Partial signatures

oleg at pobox.com oleg at pobox.com
Fri Aug 6 23:29:40 EDT 2004


Malcolm Wallace wrote:
> and since you cannot write a partial signature,

Can't we really?

It seems `partial signature' means one of two things:

	- we wish to add an extra constraint to the type of the function
	  but we don't wish to explicitly write the type of the
	  function and enumerate all of the constraints

	- we wish to specify the type of the function and perhaps some
          of the constraints -- and let the typechecker figure out the
	  rest of the constraints.

Both of the above is easily possible, in Haskell98.

In the first case, suppose we have a function

> foo x = Just x

and suppose we wish to add an extra constraint (Ord x) but without
specifying the full signature of the function. We just wish to add one
constraint.

> addOrd:: (Ord x) => x -> a
> addOrd = undefined
>
> foo' x | False = addOrd x
> foo' x = Just x


Even a not-so-sufficiently smart compiler should be able to eliminate
any traces of the first clause of foo' in the run code. So, the recipe
is to define a function like `addOrd' (or like an identity), give it
the explicit signature with the desired constraint, and then `mention'
that function somewhere in the body of foo. Or, as the example above
shows, prepend a clause of the form
	foo arg ... | False = addOrd arg ...
In that case, the body of the function foo does not have to be changed at
all.

For the second case: suppose we wrote a function

> bar a i = a ! i

and wish to give it a type signature

*> bar:: Array i e -> i -> e

But that won't work: we must specify all the constraints:
    Could not deduce (Ix i) from the context ()
      arising from use of `!' at /tmp/d.lhs:207
    Probable fix:
	Add (Ix i) to the type signature(s) for `bar'
    In the definition of `bar': bar a i = a ! i

But what if we wish to specify the type without the constraints (and
let the compiler figure the constraints out)? Again, the same trick
applies:

> barSig:: Array i e -> i -> e
> barSig = undefined
>
> bar' a i | False = barSig a i
> bar' a i = a ! i

Incidentally, barSig plays the role of a Java interface of a
sort. barSig is a bona fide function, and can be exported and
imported. To make sure that some other function baz satisfies the
barSig interface (perhaps with a different set of constraints), all we
need to do is to say
	baz arg1 ... | False = barSig arg1 ...

We can also attach to barSig some constraints. The typechecker will
figure out the rest, for bar' and baz.



More information about the Haskell-Cafe mailing list