If you have a multi-parameter type-class with arguments a, b, c, and x, this extension lets you express that the type x can be uniquely identified from a, b, and c:
class SomeClass a b c x | a b c -> x where ...
When declaring an instance of such class, it will be checked against all other instances to make sure that the functional dependency holds, that is, no other instance with same a b c
but different x
exists.
You can specify multiple dependencies in a comma-separated list:
class OtherClass a b c d | a b -> c d, a d -> b where ...
For example in MTL we can see:
class MonadReader r m| m -> r where ...
instance MonadReader r ((->) r) where ...
Now, if you have a value of type MonadReader a ((->) Foo) => a
, the compiler can infer that a ~ Foo
, since the second argument completely determines the first, and will simplify the type accordingly.
The SomeClass
class can be thought of as a function of the arguments a b c
that results in x
. Such classes can be used to do computations in the typesystem.