Проблема в том, что вы путаете монадические значения с чистыми значениями.
Первое, что нужно знать, это то, что нотация синтаксического сахара для обычных вызовов функций (>>=
и >>
).Таким образом, это поможет увидеть, что ваш код тоже не подходит.
Давайте попробуем что-нибудь попроще
f a b =
do one <- a + b
return one
Это та же проблема, что и ваш код, но проще.Чтобы понять, почему это не работает, мы спрашиваем: что это на самом деле означает?Что ж, мы можем переписать символ <-
, используя >>=
f a b = (a + b) >>= \x -> return x
(это не самое простое представление, но проясняет суть)
Если вы проверяете следующее в GHCi
>> :t (>>=)
Monad m => m a -> (a -> m b) -> m b
, то есть функция >>=
принимает: аргумент типа m
из a
и функцию от a
до m
из b
и возвращает m
из b
.
А что в этом коде?
(a + b)
Будет числом.Как насчет другой половины
\x -> return x
Берет объект типа a
и возвращает объект типа m a
для любого a
Итак, вам нужно иметь числоэто тоже своего рода монада чего-то.Вы можете придумать что-нибудь подобное?Непонятно, что это будет, что является причиной для подозрения, что это должно проверять тип.
Один хороший способ примириться с монадами - это взглянуть на некоторые конкретные примеры.
Монада Maybe
выражает вычисления, которые могут потерпеть неудачу
instance Monad Maybe where
return = Just
(>>=) (Just a) f = f a
(>>=) Nothing _ = Nothing
Это позволяет вам говорить вещи с шаблоном типа
f args = do x <- functionThatMightFail args
y <- anotherfunctionThatMightFail x
return y
или с тем же кодом более просто
f args = do x <- functionThatMightFail args
anotherfunctionThatMightFail x
или, возможно,
f args = functionThatMightFail args >>= anotherfunctionThatMightFail
С другой стороны, монада List
отражает идею выполнения одной и той же функции для каждого элемента списка, а затем объединяет результаты вместе.Простых примеров предостаточно:
f = do x <- [1,2,3,4]
[1..x]
Если вы понимаете эти примеры, поиграйте с монадой State
.Это поможет вам получить более общее представление о том, что «монады являются моделями вычислений».Я бы тогда проверил Parsec, и, конечно, IO