[Haskell-cafe] decoupling type classes

Yin Wang yinwang0 at gmail.com
Mon Jan 16 21:33:46 CET 2012


>>> The typical example would be
>>>
>>> instance Eq a => Eq [a] where
>>>  [] == [] = True
>>>  (a : as) == (b : bs) = a == b && as == bs
>>>  _ == _ = False
>>
>> It can handle this case, although it doesn't handle it as a parametric
>> instance. I suspect that we don't need the concept of "parameter
>> instances" at all. We just searches for instances recursively at the
>> call site:
>
> That seems like it could work, but typically, one would like
> termination guarantees for this search, to avoid the type-checker
> getting stuck...

Good point. Currently I'm guessing that we need to keep a stack of the
traced calls. If a recursive call needs an implicit parameter X which
is matched by one of the functions in the stack, we back up from the
stack and resolve X to the function found on stack.


>> foo x =
>>   let overload bar (x:Int) = x + 1
>>   in \() -> bar x
>>
>>
>> baz =
>>  in foo (1::Int)
>>
>> Even if we have only one definition of "bar" in the program, we should
>> not resolve it to the definition of "bar" inside foo. Because that
>> "bar" is not visible at the call site "foo (1::int)". We should report
>> an error in this case. Think of "bar" as a "typed dynamically scoped
>> variable" helps to justify this decision.
>
> So you're saying that any function that calls an overloaded function
> should always allow its own callers to provide this, even if a correct
> instance is in scope. Would that mean all instances have to be
> resolved from main? This also strikes me as strange, since I gather
> you would get something like "length :: Monoid Int => [a] -> Int",
> which would break if you happen to have a multiplicative monoid in
> scope at the call site?

If you already have a correct instance in scope, then you should have
no way defining another instance with the same name and type in the
scope as the existing one. This is the case for Haskell.

But it may be useful to allow nested definitions (using let) to shadow
the existing instances in the outer scope of the overloaded call.



More information about the Haskell-Cafe mailing list