Parsing
Tip
Understanding parser combinators is a prerequisite for this module. See here for information.
| Parser.hs | |
|---|---|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |  | 
- It's often useful to make a custom type for errors specific to the domain in question.
- asumcomes from the- Alternativetypeclass:- asum [x,y,z]=- x <|> y <|> z.
- either :: (a -> c) -> (b -> c) -> Either a b -> cis a useful function for handling an- Either X Y.
- Viewed with the Haskell Language Server, this will be underlined in blue, with a simplification suggested.
- Like anything else in Haskell, parsers are just values, so it's possible (and idiomatic) to put them in a list and then fold the list.
- Observe how the parser as a whole is built out of smaller parsers.
- "place"is itself a parser, thanks to OverloadedStrings.
- a <$> b = fmap a b. That is:- <$>is an infix synonym for- fmap. Example with- const:- fmap (const 1) [1,2,3,4] = [1,1,1,1]
- We abstract some boilerplate with a function that makes a simple parser given a name and return value.
- eofonly succeeds at the end of a line, so ensures there are no more characters left.
- returnis not a keyword. Here, it converts an- Instructioninto a- Parser Instruction, namely the trivial parser that does nothing and immediately returns an- Instruction. This- Parser Instructionis the final parser in the sequence of parsers in the- do-notationcode block.
- do-notation used to build a complex parser out of a series of simpler ones and their results.
- Explicit imports like this are useful both for readability and to avoid namespace clashes.
- Another way to avoid namespace clashes. Common for both Data.MapandData.Text.
- Void is the empty type. This says that the custom error type is Void(i.e. doesn't exist), and that the type of the input sequence isText.
Analysis¶
This module exists to parse user input on the command line into the Instruction type. Parsing directly into a custom type is idiomatic Haskell because it handles errors nicely: either parsing succeeds and you're guaranteed to get an Instruction, or you get an interpretable parse failure.
Note the use of word, a function which takes a parser and returns a new parser that handles white space. This abstracts white space handling to a single function, and makes for clean, idiomatic parsing.
parsePiece¶
parsePiece :: Ord a => Parsec a Text Piece
parsePiece = do
color <- word $ (const White <$> "white") <|> (const Black <$> "black")
pieceType <-
    word $
    try (const Bishop <$> "bishop")
        <|> try (const King <$> "king")
        <|> try (const Queen <$> "queen")
        <|> try (const Knight <$> "knight")
        <|> try (const Rook <$> "rook")
        <|> try (const Pawn <$> "pawn")
return (Piece pieceType color)
parseRank¶
  
    
      Last update:
      January 18, 2023
      
        
Created: August 18, 2022
  
  
                
              Created: August 18, 2022