It could. In strictly interpretational non-compiled implementation, you could represent functions as
data Function = F Source | Compo Function Function
and then you'd just define
compositionSplit (Compo f g) = Just (f,g)
compositionSplit _ = Nothing
Such implementation would treat function equality (w.r.t. referential transparency) as intensional, not extensional equality. As the language itself doesn't say anything about equality of functions AFAIK, this shouldn't affect anything (except maybe performance).
In compiled implementations this could be achieved too, e.g. by maintaining provenance for every object in memory.
AndrewC gives a winning counter-argument: for the two values a=f.(g.h)
and b=(f.g).h
, if we want to consider them as equal values - which we normally do, in Haskell - fst.unJust.deCompo
will produce two different results, breaking referential transparency. So it can't be part of pure FP paradigm. It'd have to return something which we could legitimately consider as being equal values too, in the two cases, and we wouldn't be able to take it apart, without breaking the purity. Maybe such a thing could exist in some impure monad, but that's not what OP asked for, sadly. :) So this answer is in error.