With Peano-style type-level naturals, it's fairly easy to write an absolute difference type-level function (aka type family):
{-# LANGUAGE DataKinds, StandaloneKindSignatures, TypeFamilies #-}
module Nat where
data Nat = Z | S Nat
type AbsDiff :: Nat -> Nat -> Nat
type family AbsDiff x y where
AbsDiff x Z = x
AbsDiff Z y = y
AbsDiff (S x) (S y) = AbsDiff x y
GHC.TypeLits.Nat is a more efficient way to represent and manipulate the type-level naturals, compared to a unary representation. However, I don't see how to define AbsDiff for GHC.TypeLits.Nat without resorting to unary subtraction. GHC.TypeLits.CmpNat exists, and I could imagine using it like this (hypothetical syntax):
{-# LANGUAGE DataKinds, StandaloneKindSignatures, TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Nat
import GHC.TypeLits
type family AbsDiff x y where
CmpNat x y ~ LT => AbsDiff x y = y - x
CmpNat x y ~ EQ => AbsDiff x y = 0
CmpNat x y ~ GT => AbsDiff x y = x - y
But there appears to be no way to constrain a type family instance. This makes sense, as constraints don't guide typeclass resolution, and type families presumably work similarly.
Is there any way to write an efficient AbsDiff for GHC.TypeLits.Nat?