I’m working through the GADTs for dummies tutorial and I’m having trouble understanding the Replace
type class:
Another example is a class that replaces all occurrences of ‘a’ with ‘b’ in type ‘t’ and return the result as ‘res’:
class Replace t a b res
instance Replace t a a t
instance (Replace t a b res) => Replace [t] a b [res]
instance Replace t a b t
(Omitted a couple of instances for brevity.) I’m reading this as: A Replace [t] a b [t]
matches the third line, for which the constraint matches the fourth line, resulting in Replace [t] a b [t]
. A Replace [t] a a [t]
also matches the third line, but for which the constraint matches the second line, resulting in Replace [t] a a [t]
. Either I am not understanding how instances are selected, and/or that there is something about how the type replacement is encoded that I don’t get. Can someone break this down for me?
There’s also a paragraph about instance selection order:
In many other cases this automatic selection is not powerful enough and we are forced to use some artificial tricks or complain to the language developers. The two most well-known language extensions proposed to solve such problems are instance priorities, which allow us to explicitly specify instance selection order, and ‘/=’ constraints, which can be used to explicitly prohibit unwanted matches:
instance Replace t a a t
instance (a /= b) => Replace [t] a b [Replace t a b]
instance (a /= b, t /= [_]) => Replace t a b t
What extensions are being referred to here? There doesn’t seem to be any InstancePriorities
.