Почему объединение автономно, а не часть MINIMAL-реализации класса Monad?

Я бы предпочел определить экземпляр Monad через функцию join вместо >> =... Начиная с этой эквивалентности:

x >>= f = join (fmap f x)

так что вы можете определить экземпляр Monad только для соединения?

Я ожидал бы присоединиться к Монаде с помощью: {-# MINIMAL (>>=)| join #-} {-# MINIMAL (>>=)| join #-}

Почему join на верхнем уровне и даже не в стиле Monad?

Ответы

Ответ 1

К сожалению, join не входит в стандартную библиотеку Monad в стандартной библиотеке GHC из-за технических ограничений, связанных с генерацией нового типа и системой ролей. Короче говоря, учитывая некоторый newtype T ma = MkT (ma), GHC недостаточно умен, чтобы выяснить, как доказать репрезентативное равенство между m (ma) и m (T ma), что необходимо для доказательства репрезентативного равенства для первый аргумент join (который имеет тип m (ma) → ma).

К счастью, недавнее расширение GHC Haskell, QuantifiedConstraints, может позволить сделать систему ролей достаточно умной, чтобы поддержать это. Более подробное рассмотрение проблемы и ее возможного решения см. В блоге Ryan Scotts, " Как QuantifiedConstraints" позволяет нам присоединиться к группе в Монаде.

Ответ 2

join не входит в Monad потому что он сломал GeneralizedNewtypeDeriving тонким способом для новомодных конвертеров с монадами, очень распространенный вариант использования. См. Wiki для GHC.

Ответ 3

join не определено в классе Applicative. Проверьте отступ; все методы класса отступы, а join - нет. Так что это не метод класса.

К сожалению, join не входит в класс Monad, поэтому нет возможности определить класс таким образом. join определяется одинаково для всех монад.

В настоящее время лучшее, что вы можете сделать, это определить функцию myCustomJoin, а затем использовать ее в определении экземпляра Monad >>=.