#haskell #monads
#haskell #монады
Вопрос:
Как мне написать эту функцию с помощью оператора >>=?
parseNumber2 :: Parser LispVal
parseNumber2 = do x <- many1 digit
return $ (Number . read) x
Ответ №1:
Простое удаление обозначения do дает
parseNumber2 :: Parser LispVal
parseNumber2 = many1 digit >>= (return . Number . read)
но более идиоматичным способом является использование fmap
или эквивалентного <$>
оператора из Control.Applicative
parseNumber2 = Number . read <$> many1 digit
Для десугаризации do-нотации:
-
Переверните любые
<-
привязки на правую сторону и добавьте>>=
абстракцию lambdado x <- a y <- b ...
становится
a >>= x -> b >>= y -> ...
-
Для любых необязательных форм добавьте
>>
справа:do a b ...
становится
a >> b >> ...
-
Оставьте последнее выражение в покое.
do a
становится
a
Применяя эти правила к вашему коду, мы получаем
parseNumber2 =
many1 digit >>= x ->
return $ (Number . read) x
Сделайте некоторые упрощения
parseNumber2 = many1 digit >>= x -> (return . Number . read) x
parsenumber2 = many1 digit >>= (return . Number . read)
Теперь для любой монады fmap
или <$>
может быть определено как
f <$> x = x >>= (return . f)
Используйте это, чтобы получить идиоматическую форму
parseNumber2 = Number . read <$> many1 digit
Комментарии:
1. Смотрите также RWH # Удаление блоков do и Haskell 2010 > Выражения # Do