型レベルのバインディングは書けないので、以下のようにパターンごとに分けて定義することになります。再帰の場合は反復形(末尾再帰?)で定義するほうが定義しやすいと思います。
data Nat
= Z
| S Nat
type family (m :: Nat) + (n :: Nat) :: Nat where
Z + n = n
S m + n = S (m + n)
type family (m :: Nat) - (n :: Nat) :: Nat where
Z - n = Z
m - Z = m
S m - S n = m - n
type family Cmp (m :: Nat) (n :: Nat) :: Ordering where
Cmp Z Z = EQ
Cmp Z (S n) = LT
Cmp (S m) Z = GT
Cmp (S m) (S n) = Cmp m n
type family DivMod (m :: Nat) (n :: Nat) :: (Nat, Nat) where
DivMod m n = DivModIter Z (Cmp m n) m n
type family DivModIter (d :: Nat) (o :: Ordering) (m :: Nat) (n :: Nat) :: (Nat, Nat) where
DivModIter d o Z (S b) = '(d , Z)
DivModIter d 'EQ (S a) (S b) = '(S d, Z)
DivModIter d 'LT (S a) (S b) = '(d, S a)
DivModIter d 'GT (S a) (S b) = DivModIter (S d) (Cmp (a - b) (S b)) (a - b) (S b)
type N2 = S (S Z)
type N5 = N2 + S N2
これで、たとえば
>>> :kind! DivMod N5 N2
DivMod N5 N2 :: (Nat, Nat)
= '( 'S ('S 'Z), 'S 'Z)
ですかね。