The recently released `Seqes`

library offers functors to mix the `Stdlib.Seq`

abstraction with monads. The original impetus for development was the use of Lwt, result and Lwt+result monads in the octez code-base. The use of these monads in combination with `Seq`

introduced a lot of boilerplate code, which `Seqes`

aims to alleviate.

# Code duplication in Seqes

The Lwt “monad” (something something exceptions can break one of the monadic law) has one parameter. Thus the functor allowing to define a Seq+Lwt module is:

```
module Make1
(Mon: sig
type 'a t
val return : 'a -> 'a t
val bind : 'a t -> ('a -> 'b t) -> 'b t
end)
: S1
with type 'a mon := 'a Mon.t
= struct
(* code here *)
end
```

The Result monad has two parameters. Thus the functor for defining a Seq+Result module is:

```
module Make2
(Mon: sig
type ('a, 'e) t
val return : 'a -> ('a, 'e) t
val bind : ('a. 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t
end)
: S2
with type ('a, 'e) mon := ('a, 'e) Mon.t
= struct
(* code here *)
end
```

Interestingly, there is no difference in the code of the two functor apart from type definition.

Technically, it’s worse than just that:

- There is a (duplicated) functor for making traversors over the
`Stdlib.Seq.t`

. - There is a (duplicated) functor as presented above.
- There is a (duplicated) functor inside the functor presented above formaking additional traversors.

But the observation is still valid: only the types differ, the control structures are 1-to-1 identical. The library is essentially fully duplicated: there’s a one-parameter version and two-parameter version.

# Can I encode the arity of a type constructor in the type system and use that to deduplicate the code?

Of course once can pass a two-parameter monad as a one-parameter monad. The two-parameter functor will accept the following monad:

```
type ('a, 'e) t = 'a Lwt.t
let return = Lwt.return
let bind = Lwt.bind
```

But this returns a two-parameter Seq-like type.

I notice that the `kinded`

and `higher_kinded`

libraries have a similar approach of duplicating the code for each arity of the type constructor. And I think that if there was a known trick it would be used in those libraries.

Anyone has examples? Ideas?

Alternatively, explanations as to why it’s not possible?