25.10.2015 Views

Write You a Haskell Stephen Diehl

1kEcQTb

1kEcQTb

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Extensible Operators<br />

<strong>Haskell</strong> famously allows the definition of custom infix operators, and extremely useful language feature<br />

although this poses a bit of a challenge to parse! ere are several ways to do this and both depend on<br />

two properties of the operators.<br />

• Precedence<br />

• Associativity<br />

1. e first is the way that GHC does is to parse all operators as left associative and of the same<br />

precedence, and then before desugaring go back and “fix” the parse tree given all the information<br />

we collected after finishing parsing.<br />

2. e second method is a bit of a hack, and involves simply storing the collected operators inside<br />

of the Parsec state monad and then simply calling buildExpressionParser on the current state<br />

each time we want to parse and infix operator expression.<br />

To do later method we set up the AST objects for our fixity definitions, which associate precedence and<br />

associativity annotations with a custom symbol.<br />

data FixitySpec = FixitySpec<br />

{ fixityFix :: Fixity<br />

, fixityName :: String<br />

} deriving (Eq, Show)<br />

data Assoc<br />

= L<br />

| R<br />

| N<br />

deriving (Eq,Ord,Show)<br />

data Fixity<br />

= Infix Assoc Int<br />

| Prefix Int<br />

| Postfix Int<br />

deriving (Eq,Ord,Show)<br />

Our parser state monad will hold a list of the at Ivie fixity specifications and whenever a definition is<br />

uncounted we will append to this list.<br />

data ParseState = ParseState<br />

{ indents :: Column<br />

, fixities :: [FixitySpec]<br />

} deriving (Show)<br />

139

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

Saved successfully!

Ooh no, something went wrong!