Thanks for the reply. I don't quite understand why guessing whether there is an intermediate type would be so magical, though. Let's simplify:data Adata Bclass IsNotFirst aclass IsAfter b ainstance (IsAfter b a) => IsNotFirst ainstance IsAfter B AHere we've separated out the ambiguous type issue from the unification. Note that *already*, if I query with undefined::(IsNotFirst A => a), I get:No instance for (IsAfter b A) arising from a use of ‘t’The type variable ‘b’ is ambiguousNote: there is a potential instance available:instance [overlap ok] IsAfter B AGenerally, GHC is doing the work that I wanted it to *in the error message*. In what sense, then, is this impossible?And why is there some inexcusable use of CWA here? Instances already have (if you squint) a negation-as-failure semantics. "instance (IsAfter b a) => IsNotFirst a" doesn't *in that sense* look that different to me than "instance (IsSecond a) => IsNotFirst a": adding extra instance declarations can 'change the truth-value' of the right-hand side.Thanks again,JulianOn Thu, Jun 26, 2014 at 1:58 AM, Andras Slemmer <0slemi0@gmail.com> wrote:
It is the existential that is emulated with the cwa and cannot be emulated in haskell's typesystem.\forall A,C.(path(A,C) <- \exists B.(path(A,B)^path(B,C)))If you translate this to first order logic you'd have:(havent used prolog for a while so syntax might be off)path(A,C) :- path(A,B), path(B,C).In prolog you'd have something like this:Think about what you're asking from the compiler. If it sees a (Path a c) constraint it would have to magically guess whether there is an intermediate type b for which (Path a b) and (Path b c), which is impossible.
Logic programming relies on the closed world assumption, meaning that if a statement cannot be proven within the closed world we are working in then it is false. Haskell typeclasses don't work like this; there is no closed world of types, so the compiler cannot "refute" a constraint.