Thanks, that looks promising. I've also discovered some tricks:1. With TypeFamilies and PartialTypeSignatures one can write: test :: _ => FixedGetter i j (Int32, Int32, Int32, Int32) where test's body is: int32Host >>>= \a -> int32Host >>>= \b -> int32Host >>>= \c -> int32Host >>>= \d -> ireturn (a, b, c, d). Haskell will infer that "_" (skipped type context with some type-level math on i and j) is a (KnownNat i), ((KnownNat (i + 4)), (KnownNat (i + 4) + 4) and so on freeing the programmer from declaring all of this manually.
2. One can specify types explicitly. For example test :: FixedGetter 0 16 (Int32, Int32, Int32, Int32) works, unexpectedly.