You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
-- Start of layout ( Column: 0 )<br />
fib :: Int -> Int<br />
fib x = truncate $ ( 1 / sqrt 5 ) * ( phi ^ x - psi ^ x ) -- (Column: > 0)<br />
-- Start of new layout ( Column: 2 )<br />
where<br />
-- Indented block ( Column: > 2 )<br />
phi = ( 1 + sqrt 5 ) / 2<br />
psi = ( 1 - sqrt 5 ) / 2<br />
e Parsec monad is itself parameterized over a type variable s which stands for the State layer baked<br />
into the monad allowing us to embed custom parser state inside of our rules. To adopt our parser to<br />
handle sensitive whitespace we will<br />
-- Indentation sensitive Parsec monad.<br />
type IParsec a = Parsec Text ParseState a<br />
data ParseState = ParseState<br />
{ indents :: Column<br />
} deriving (Show)<br />
initParseState :: ParseState<br />
initParseState = ParseState 0<br />
Inside of the Parsec the internal position state (SourcePos) is stored during each traversal, and is accessible<br />
inside of rule logic via getPosition function.<br />
data SourcePos = SourcePos SourceName !Line !Column<br />
getPosition :: Monad m => ParsecT s u m SourcePos<br />
In terms of this function we can write down a set of logic that will allow us to query the current column<br />
count and then either succeed or fail to match on a pattern based on the current indentation level. e<br />
laidout combinator will capture the current indentation state and push it into the indents field in the<br />
State monad.<br />
laidout :: Parsec s ParseState a -> Parsec s ParseState a<br />
laidout m = do<br />
cur