Я пишу библиотеку с интерфейсами 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
- Как уменьшить дублирование кода, когда класс реализует несколько «конечных точек» (например, возможно, это MonadPlus и MonadFix, Kleisli - это ArrowEverything)
- Стрелка теоретически может также расширять Аппликатив. В настоящее время у меня есть метод для Arrow, возвращающий этот Applicative, потому что, похоже, что тип curring делает наследование здесь невозможным.
- Есть ли другие неочевидные "связи" (например, Arrow-> Applicative), по которым я скучаю?
- Какие классы "полезных" типов отсутствуют в этой иерархии?