[Haskell-cafe] newbie type signature question

Brian Hulley brianh at metamilk.com
Mon Jun 12 17:11:37 EDT 2006


Bulat Ziganshin wrote:
> Hello Brian,
>
> Saturday, June 10, 2006, 3:05:25 AM, you wrote:
>
>> It is possible that this feature was added to the language for the
>> benefit of people who prefer not to use explicit type signatures but
>> afaiu this goes against best practice where everything should always
>> have an explicit signature to make code easy to understand and
>> facilitate debugging of type errors.
>
> when you work with C++ or some other OOP language, you can define that
> some field in structure should some some specific interface and this
> allows to use functions of this interface on this field. i required
> the same feature in Haskell, for example:
>
> data UTF8Stream h = (ByteStream h) => UTF8Stream h
>
> instance TextStream (UTF8Stream h) ...
>
> addUTF8Encoding :: h -> (UTF8Stream h)
>
> and so on. currently i should add type constraint to each and every
> class and function i declared.

Hello Bulat -
Thanks for the example. Afaiu, if you don't write any type signature at all, 
type inference will infer the constraint, at least this is what I understand 
from http://haskell.org/onlinereport/decls.html section 4.2.1:

    data Eq a => Set a = NilSet | ConsSet a (Set a)
    Pattern matching against ConsSet also gives
    rise to an Eq a constraint. For example:

          f (ConsSet a s) = a

    the function f has inferred type Eq a => Set a -> a.

At the moment when you have an explicit type signature you can see exactly 
what the function needs, so that if you later refactored the code you could 
see which functions actually used the Eq a constraint and which ones didn't. 
For example a function to find the size of a set probably wouldn't need Eq 
a.

So if the compiler was allowed to add a context to an explicit type 
signature you would no longer be able to just look at the type signature for 
a function to find out what it was making use of - you'd need to also look 
at all the data declarations and gather all the constraints together, to 
arrive at the full type signature.

Nevertheless I suppose it would be useful to have some kind of compiler flag 
to allow this - certainly given that contexts are allowed on data 
declarations it is kind of awkward having to "repeat" all the info on each 
function that uses that type, since at the moment the only way to avoid this 
repetition is to avoid giving functions that use that type any type 
signatures at all, which seems worse.

Or perhaps there could be a special syntax to indicate a partial type 
signature, that the compiler would complete by adding the contexts eg:

      f ::: Set a -> a
        ^^^ ? 3 colons to indicate that the compiler will add the relevant 
context(s)

> i don't tried using existential types
> here, so i'm not sure that they will give the same high speed for
> inlined functions. moreover, they "lose" information about other type
> classes that 'h' supports, although functions from these classes may
> be required for application that use "UTF8Stream h" and even by other
> definitions in my lib:
>
> instance (ByteStringStream h) => ByteStringStream (UTF8Stream h) ...

Yes I also think they'd be slower and not recommended unless they're 
actually needed eg for getting a common interface to objects whose concrete 
types aren't known at compile time (being like virtual functions in C++). I 
just mentioned them as an example of something not relevant to the 
guideline. (Whoever wrote the guideline might have had more reasons but 
that's all I can think up so far.)

Best regards, Brian.

-- 
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 



More information about the Haskell-Cafe mailing list