Почему объединение автономно, а не часть 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
>>=
.