Это обозначение, специфичное для «базы: ghc.cas.monad»?
Вопрос
Идея, что стандарт Monad
класс ошибочно и что он должен продлить Functor
или Pointed
плавает вокруг.
Я не обязательно утверждаю, что это правильная вещь, но предположим, что кто-то пытался сделать это:
import Prelude hiding (Monad(..))
class Functor m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
join = (>>= id)
(>>=) :: m a -> (a -> m b) -> m b
a >>= t = join (fmap t a)
(>>) :: m a -> m b -> m b
a >> b = a >>= const b
До сих пор так хорошо, но потом, когда пытаясь использовать обозначение:
whileM :: Monad m => m Bool -> m ()
whileM iteration = do
done <- iteration
if done
then return ()
else whileM iteration
Компилятор жалуется:
Could not deduce (base:GHC.Base.Monad m) from the context (Monad m)
Вопрос:
Делает работу только для обозначения только для base:GHC.Base.Monad
? Есть ли способ сделать его работать с альтернативой Monad
класс?
Дополнительный контекст:
Что я действительно хочу сделать, это заменить base:Control.Arrow.Arrow
с «обобщенным» Arrow
класс:
{-# LANGUAGE TypeFamilies #-}
class Category a => Arrow a where
type Pair a :: * -> * -> *
arr :: (b -> c) -> a b c
first :: a b c -> a (Pair a b d) (Pair a c d)
second :: a b c -> a (Pair a d b) (Pair a d c)
(***) :: a b c -> a b' c' -> a (Pair a b b') (Pair a c c')
(&&&) :: a b c -> a b c' -> a b (Pair a c c')
А затем используйте Arrow
Обозначение вопросов с моим Arrow
класс, но это терпит неудачу в примере выше обозначения и Monad
.
Я буду использовать в основном Either
Как мою пару тип конструктора, а не (,)
Тип конструктора как с током Arrow
класс. Это может позволить сделать код моей игрушечной игры RTS (cabal install DefendTheKind
) намного красивее.
Решение
Вам нужно использовать NoimpliTPrelude расширение Для полного восстановительного синтаксиса, в том числе do
и proc
. Отказ В этом случае вы получаете следующее, среди прочего:
Обозначение «Do» переводится с использованием любых функций (>> =), (>>) и сбой, находятся в области (не версии Prelude). Сообщение списка, MDO (раздел 7.3.6, «рекурсивная передача данных»), а также параллельные комплектные массивы, не затрагиваются.
Вы также можете настроить некоторую обработку отрицания, равенства, буквальными ценностями и othernot. Отличный способ запугивать код!
PS - если вы собираетесь перекоснуть do
синтаксис, Какие SIGFPE называет «параметризованные монады» очень весело. Та же идея доступна в category-extras
под Control.Monad.indexed. Отказ И да, они работают с восстановительным синтаксисом, несмотря на дико разные подписи типа!