I write a library with Java interfaces resembling Haskell type classes, and abstract classes implementing all "derivable" methods (e.g. Monad.join
can be written using >>=
and return
). This 开发者_开发问答is my planned structure ([] means the interface doesn't exist yet):
Applicative <= Alternative <-,
Functor <= Pointed <= Applicative <= Monad <= MondPlus
Functor <= Copointed <= Comonad Monad <= [MonadFix]
Category <= Arrow <= ArrowChoice
Arrow <= [ArrowApply]
Arrow <= [ArrowLoop]
Arrow <= [ArrowZero] <= [ArrowPlus]
Bifunctor
- Is this hierarchy "correct"?
- Particularly, is it correct that MonadPlus implements Alternative?
- Should I split MonadZero from MonadPlus? Same question for ArrowZero and ArrowPlus
- How can I reduce code duplication when a class implements multiple "endpoints" (e.g. Maybe is a MonadPlus and a MonadFix, Kleisli is ArrowEverything)
- Arrow could theoretically extend Applicative as well. Currently I have a method on Arrow returning that Applicative, because it looks like type curring makes inheritance impossible here.
- Are there other non-obvious "connections" (like Arrow->Applicative) I'm missing?
- Which "useful" type classes are missing in this hierarchy?
You should make sure to consult the typeclassopedia.
Edward Kmett has been doing yeoman's work in trying to construct a rich, sane, hierarchy of core classes, starting with semigroups and moving forward. It's worth corresponding with him directly, but take a look at semigroupoids and the many related packages he's uploaded for some pointers:
精彩评论