acple
acple

Reputation: 75

How to use instance chain to solve overlapping

I'm having trouble with instance chaining in PureScript version 0.12.0-rc1. The way I understand it, an instance chain allows one to specify instance resolution order explicitly to avoid instance definition overlapping.

I came up with the following example, but it won't compile:

class A a
class B b
class C c where
  c :: c -> String

instance ca :: A a => C a where
  c = const "ca"
else
instance cb :: B b => C b where
  c = const "cb"

data X = X
instance bx :: B X

main :: forall eff. Eff (console :: CONSOLE | eff) Unit
main = logShow $ c X

What did I do wrong? Is my use of instance chaining incorrect?

Here's the full error message:

Error found:
in module Main
at src/Main.purs line 23, column 8 - line 23, column 20

  No type class instance was found for

Main.A X


while applying a function c
  of type C t0 => t0 -> String
  to argument X
while inferring the type of c X
in value declaration main

where t0 is an unknown type

Upvotes: 3

Views: 455

Answers (1)

paluh
paluh

Reputation: 2231

Even with instance chains matching is still done on the head of an instance. There is no "backtracking" when any of constraint fails for the chosen instance.

Your instances are completely overlapping on the head, so your first instance always matches before second one and it fails because there is no A instance for X.

Instance chains allows you to define explicit ordering of instance resolution without relying on for example alphabetical ordering of names etc. (as it was done till 0.12.0 version - please check the third paragraph here). For example you can define this overlapping scenario:

class IsRecord a where
   isRecord :: a -> Boolean

instance a_isRecordRecord :: IsRecord (Record a) where
   isRecord _ = true

instance b_isRecordOther :: IsRecord a where
   isRecord _ = false

as

instance isRecordRecord :: IsRecord (Record a) where
   isRecord _ = true
else instance isRecordOther :: IsRecord a where
   isRecord _ = false

I hope it compiles - I don't have purs-0.12.0-rc yet ;-)

Upvotes: 3

Related Questions