So I would like to implement a function that applies a value to the nth argument of a function, lets call it inject
:
inject :: (???) => a -> f -> ???
So I declared a class representing all Applicable triples (n, a, f). Note that n
must be bigger than 0 and a
depends on f
and n
class (1 <= n) => Applicable n a f | f n -> a where
type ApplyAt n a f :: Type
inject :: a -> f -> ApplyAt n a f
We can then do some induction on n
:
instance Applicable 1 a (a -> b) where
type ApplyAt 1 a (a -> b) = b
inject a f = f a
instance (Applicable (n - 1) a c) => Applicable n (a :: Type) (b -> c) where
type ApplyAt n a (b -> c) = b -> ApplyAt (n - 1) a c
inject a f = \x -> inject @(n - 1) a (f x)
Applicable n a (b -> c)
implies Applicable (n - 1) a c
which implies n - 1 >= 1
or n >= 2
so these instance declarations are not overlapping. But GHC proceeds to complain:
Conflicting family instance declarations:
ApplyAt 1 a (a -> b) = b
ApplyAt n a (b -> c) = b -> ApplyAt (n - 1) a c
What should I do to convince GHC that these type familiy declarations are not overlapping?