Haskell can do this, although it's pretty unidiomatic:
data AlignedFunctionList a b where
Identity :: AlignedFunctionList x x
Pipe :: (x -> y) -> AlignedFunctionList y z -> AlignedFunctionList x z
pipe :: AlignedFunctionList a b -> (a -> b)
pipe Identity a = a
pipe (Pipe f g) a = pipe g (f a)