Я пишу библиотеку с интерфейсами Java, напоминающими классы типов Haskell, и абстрактными классами, реализующими все "производные" методы (например, Monad.join
можно записать с использованием >>=
и return
). Это моя запланированная структура ([] означает, что интерфейс еще не существует):
Applicative <= Alternative <-,
Functor <= Pointed <= Applicative <= Monad <= MondPlus
Functor <= Copointed <= Comonad Monad <= [MonadFix]
Category <= Arrow <= ArrowChoice
Arrow <= [ArrowApply]
Arrow <= [ArrowLoop]
Arrow <= [ArrowZero] <= [ArrowPlus]
Bifunctor
- Эта иерархия «правильная»?
- В частности, правильно ли, что MonadPlus реализует альтернативу?
- Стоит ли отделить MonadZero от MonadPlus? Тот же вопрос для ArrowZero и ArrowPlus
- Как уменьшить дублирование кода, когда класс реализует несколько «конечных точек» (например, Maybe - это MonadPlus и MonadFix, Kleisli - это ArrowEverything)
- Arrow теоретически может также расширить Applicative. В настоящее время у меня есть метод Arrow, возвращающий этот Applicative, потому что похоже, что curring типа делает здесь наследование невозможным.
- Есть ли другие неочевидные "связи" (например, Arrow-> Applicative), которые мне не хватает?
- Какие «полезные» классы типов отсутствуют в этой иерархии?