Как мне написать следующую функцию с оператором >> = - PullRequest
3 голосов
/ 28 апреля 2011

Как мне написать эту функцию, используя оператор >> =?

parseNumber2 :: Parser LispVal
parseNumber2 = do x <- many1 digit
                  return $ (Number . read) x

1 Ответ

13 голосов
/ 28 апреля 2011

Простая десагеринг до-нотации дает

parseNumber2 :: Parser LispVal
parseNumber2 = many1 digit >>= (return . Number . read)

, но более идиотский способ - использовать fmap или эквивалентный оператор <$> из Control.Applicative

parseNumber2 = Number . read <$> many1 digit

Для десугарских обозначений:

  1. Переверните любые <- привязки на правую сторону и добавьте >>= и лямбда-абстракцию

    do x <- a
       y <- b
       ...
    

    становится

    a >>= \x ->
    b >>= \y ->
    ...
    
  2. Для любых необязательных форм добавьте >> справа:

    do a
       b
       ...
    

    становится

    a >>
    b >>
    ...
    
  3. Оставьте последнее выражение в покое.

    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
...