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