Why context is not considered when selecting typeclass instance in Haskell?

后端 未结 4 1388
生来不讨喜
生来不讨喜 2020-12-15 22:52

I understand that when having

instance (Foo a) => Bar a
instance (Xyy a) => Bar a

GHC doesn\'t consider the contexts, and the instanc

4条回答
  •  盖世英雄少女心
    2020-12-15 23:34

    Adding backtracking would make instance resolution require exponential time, in the worst case.

    Essentially, instances become logical statements of the form

    P(x) => R(f(x)) /\ Q(x) => R(f(x))
    

    which is equivalent to

    (P(x) \/ Q(x)) => R(f(x))
    

    Computationally, the cost of this check is (in the worst case)

    c_R(n) = c_P(n-1) + c_Q(n-1)
    

    assuming P and Q have similar costs

    c_R(n) = 2 * c_PQ(n-1)
    

    which leads to exponential growth.

    To avoid this issue, it is important to have fast ways to choose a branch, i.e. to have clauses of the form

    ((fastP(x) /\ P(x)) \/ (fastQ(x) /\ Q(x))) => R(f(x))
    

    where fastP and fastQ are computable in constant time, and are incompatible so that at most one branch needs to be visited.

    Haskell decided that this "fast check" is head compatibility (hence disregarding contexts). It could use other fast checks, of course -- it's a design decision.

提交回复
热议问题