Sometimes it is convenient to have an inheritance structure on interfaces: For example:
- I want to define an interface
Functorthat provides a function fmap. - I want to define an interface
Applicativethat provides functions fapplyand pure.
But each application is a functor: (def fmap #(fapply (pure %1) %2)).
The first solution I came to is the following:
- Define
Functorand Applicativeas independent protocols. - Define a function
functor?that returns truefor any instance of Functoror Applicative. - Define a
fmapmulimethod that can accept Functoreither Applicativeand sends before #(functor/fmap %1 %2)or #(applicative/fapply (applicative/pure %1) %2).
However, these solutions smell like it is like cheating a system like clojure.
The second solution is to define a macro extend-applicativethat will automatically implement the protocol Functor. But this solution does not look very good, because it requires additional work from the library user and allows you to separate the definition of functional / applicative instances, which can easily lead to an error.
Is there a better way to express such a relationship in clojure?
source
share