25.10.2015 Views

Write You a Haskell Stephen Diehl

1kEcQTb

1kEcQTb

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

cannot proceed because the reduction simply isn’t well-defined. e rules for evaluation are a single step<br />

by which an expression takes a single small step from one form to another by a given rule.<br />

eval’ x = case x of<br />

IsZero Zero<br />

-> Just Tr<br />

IsZero (Succ t) | isNum t -> Just Fl<br />

IsZero t -> IsZero (eval’ t)<br />

Succ t -> Succ (eval’ t)<br />

Pred Zero<br />

-> Just Zero<br />

Pred (Succ t) | isNum t -> Just t<br />

Pred t -> Pred (eval’ t)<br />

If Tr c _ -> Just c<br />

If Fl _ a<br />

-> Just a<br />

If t c a<br />

-> (\t’ -> If t’ c a) eval’ t<br />

_<br />

-> Nothing<br />

At the toplevel we simply apply eval’ repeatedly until either a value is reached or we’re left with an expression<br />

that has no well-defined way to proceed. e term is “stuck” and the program is in an undefined<br />

state.<br />

nf x = fromMaybe x (nf eval’ x)<br />

eval :: Expr -> Maybe Expr<br />

eval t = case nf t of<br />

nft | isVal nft -> Just nft<br />

| otherwise -> Nothing -- term is ”stuck”<br />

REPL<br />

e driver for our simple language simply invokes all of the parser and evaluation logic in a loop feeding<br />

the resulting state to the next iteration. We will use the haskeline library to give us readline interactions<br />

for the small REPL. Behind the scenes haskeline is using readline or another platform-specific system<br />

library to manage the terminal input. To start out we just create the simplest loop, which only parses<br />

and evaluates expressions and prints them to the screen. We’ll build on this pattern in each chapter,<br />

eventually ending up with a more full-featured REPL.<br />

e two functions of note are the operations for the InputT monad transformer.<br />

runInputT :: Settings IO -> InputT IO a -> IO a<br />

getInputLine :: String -> InputT IO (Maybe String)<br />

When the user enters an EOF or sends a SIGQUIT to input, getInputLine will yield Nothing and can<br />

handle the exit logic.<br />

41

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!