  Structured recursion schemes such as folds and unfolds have been widely used
for structuring both functional programs and program semantics. In this
context, it has been customary to implement denotational semantics as folds
over an inductive data type to ensure termination and compositionality.
Separately, operational models can be given by unfolds, and naturally not all
operational models coincide with a given denotational semantics in a meaningful
way. To ensure these semantics are coherent it is important to consider the
property of full abstraction which relates the denotational and the operational
model. In this paper, we show how to engineer a compositional semantics such
that full abstraction comes for free. We do this by using distributive laws
from which we generate both the operational and the denotational model. The
distributive laws ensure the semantics are fully abstract at the type level,
thus relieving the programmer from the burden of the proofs.
