Library
Module
Module type
Parameter
Class
Class type
Manipulating the set of traits implemented by a provider.
This module provides functions for creating an interface, as well as retrieving and extending the traits implemented by an interface, making it easy to manage the functionalities that a provider supports.
An interface is essentially a collection of traits that a provider implements, each of which providing a specific functionality (one trait implementation = one first-class module with type t = 't).
't
is the internal state of the provider.'tags
indicate which functionality are supported by the provider. It is a phantom type using polymorphic variants. To give an example, in the tests for this library, we have two modules defining each their own tag:module Directory_reader = struct
type tag = [ `Directory_reader ]
end
module File_reader = struct
type tag = [ `File_reader ]
end
Then, the type of the interface for a provider whose internal state is state
, that would implement both functionalities would be:
(state, [ Directory_reader.tag | File_reader.tag ]) Provider.Interface.t
val make : 't Trait.Implementation.t Base.list -> ('t, _) t
make implementations
create a new interface from a list of implementation. It only keeps the last implementation supplied for each trait. This means that the resulting interface will not contain any duplicate traits, and the order of the implementations in the input list can affect its contents.
val implementations : ('t, _) t -> 't Trait.Implementation.t Base.list
implementations t
returns a list of trait implementations that the interface t
supports. See also extend
.
val extend :
('t, _) t ->
with_:'t Trait.Implementation.t Base.list ->
('t, _) t
extend t ~with_
extends the interface t
and returns a new interface that includes both the original and additional implementations. The resulting interface only contains the last occurrence of each trait, prioritizing the rightmost elements in the combined list implementations t @ with_
.
A lookup operation is used to retrieve the implementation of a specific trait within an interface.
val is_empty : ('t, _) t -> Base.bool
is_empty t
checks if an interface t
implements any traits. An empty interface may be created using make []
. It will cause any lookup operation to fail. It can be useful for initializing data structures or providing a base case for algorithms that process interfaces.
lookup t ~trait
retrieves the implementation for a given trait
from an interface.
If the provider has correctly exported their implementation using the appropriate tags, the compiler will ensure that this function does not fail in user code (a failure of this function would typically indicate a programming error in the provider's setup).
lookup_opt t ~trait
returns the implementation of the trait
(Some implementation
) or indicates that the trait is not implemented (None
).
This is particularly useful in scenarios where a part of a program needs to adapt behavior at runtime based on whether certain functionalities are available or not.