Home > Enterprise >  Expressing basic number parser using >>=
Expressing basic number parser using >>=

Time:09-17

I am working through the WikiBook "Write Yourself A Scheme in 48 Hours."

The Haskell library Parsec is being used to parse basic expressions, such as numbers (as shown in the code below).

import Lib
import Text.ParserCombinators.Parsec hiding (spaces)
import System.Environment

import Control.Monad

import Data.Typeable ( typeOf )

import Debug.Trace


data LispVal = Atom String 
             | List [LispVal] 
             | DottedList [LispVal] LispVal
             | Number Integer 
             | String String 
             | Bool Bool 
    deriving Show
-- ...
parseNumber :: Parser LispVal
parseNumber = do
                x <- many1 digit
                return $ Number (read x)

One of the exercises in the book asks the reader to rewrite parseNumber using >>= notation instead. However, I keep running into scary-looking type mismatch errors. Can someone please show me how to rewrite the function using >>= notation? Or at least give me a hint?

CodePudding user response:

The Haskell report has a section on do notation and how to "desugar" these do blocks.

If you write a do block as:

parseNumber = do
    x <- many1 digit
    return (Number (read x))

Then this is syntactically equivalent to:

parseNumber :: Parser LispVal
parseNumber = many1 digit >>= \x -> return (Number (read x))

or more elegant:

parseNumber :: Parser LispVal
parseNumber = many1 digit >>= return . Number . read

We however do not need to work with >>=. Indeed, if we want to apply a function on the item that will be constructed with the Parser, then we can use fmap :: Functor f => (a -> b) -> f a -> f b or (<$>) :: Functor f => (a -> b) -> f a -> f b for this:

parseNumber :: Parser LispVal
parseNumber = Number . read <$> many1 digit
  • Related