Я понимаю, как использовать монады, но не совсем понимаю, как их создавать. Итак, я нахожусь в пути, чтобы воссоздать монаду State.
Пока что я создал новый тип Toto (foo по-французски) и сделал его экземпляром Monad. Теперь я пытаюсь добавить к нему «функцию чтения». Я создал класс TotoReader, который объявляет функцию «получить». Но когда я пытаюсь его создать, все разваливается. GHC говорит мне, что не может вывести (m ~ r) (полная ошибка компиляции внизу).
Но когда я создаю функцию get верхнего уровня, все работает правильно.
Итак, как я могу определить функцию get в классе и действительно ли это правильный способ сделать это? Что это я не понимаю?
Мой код пока ниже
{-# OPTIONS -XMultiParamTypeClasses #-}
{-# OPTIONS -XFlexibleInstances #-}
newtype Toto s val = Toto { runToto :: s -> (val, s) }
toto :: (a -> (b,a)) -> Toto a b
toto = Toto
class (Monad m) => TotoReader m r where
get :: m r
instance Monad (Toto a) where
return a = toto $ \x -> (a,x)
p >>= v = toto $ \x ->
let (val,c) = runToto p x
in runToto (v val) c
instance TotoReader (Toto m) r where
get = toto $ \x -> (x, x) -- Error here
-- This is working
-- get :: Toto a b
-- get = toto $ \s -> (s,s)
pp :: Toto String String
pp = do
val <- get
return $ "Bonjour de " ++ val
main :: IO ()
main = print $ runToto pp "France"
Ошибка компиляции
test.hs:19:11:
Could not deduce (m ~ r)
from the context (Monad (Toto m))
bound by the instance declaration at test.hs:18:10-30
`m' is a rigid type variable bound by
the instance declaration at test.hs:18:10
`r' is a rigid type variable bound by
the instance declaration at test.hs:18:10
Expected type: Toto m r
Actual type: Toto m m
In the expression: toto $ \ x -> (x, x)
In an equation for `get': get = toto $ \ x -> (x, x)
In the instance declaration for `TotoReader (Toto m) r'
Monad
запутанным, поскольку вы использовалиToto a
в качестве типа, гдеa
— это переменная типа, представляющая состояние, но затем в реализации вы привязываетеa
к монаде value, аx
иc
в гос. Было бы меньше путаницы, если бы вы использовалиs
для переменной типа иs
иs'
для привязки состояния. - person pat   schedule 31.03.2014