Fixed type and semantic errors
Getty Ritter
10 years ago
| 135 | 135 | As pointed out above, there are three different carrier types that are |
| 136 | 136 | used to represent S-expressions by the library, but you can use any |
| 137 | 137 | type as a carrier type for a spec. This is particularly useful when |
| 138 | you want to do your own parsing. For example, if we wanted to parse | |
| 139 | a small S-expression-based arithmetic language, we could define a | |
| 140 | data type and transformations from and to an S-expression type: | |
| 138 | you want to parse into your own custom tree-like type. For example, if | |
| 139 | we wanted to parse a small S-expression-based arithmetic language, we | |
| 140 | could define a data type and transformations from and to an S-expression | |
| 141 | type: | |
| 141 | 142 | |
| 142 | 143 | ~~~~.haskell |
| 143 | 144 | import Data.Char (isDigit) |
| 151 | 152 | toExpr (RSAtom c) |
| 152 | 153 | | T.all isDigit c = pure (Num (read (T.unpack c))) |
| 153 | 154 | | otherwise = Left "Non-numeric token as argument" |
| 154 |
toExpr _ = |
|
| 155 | toExpr _ = Left "Unrecognized s-expr" | |
| 155 | 156 | |
| 156 | 157 | fromExpr :: Expr -> RichSExpr Text |
| 157 | 158 | fromExpr (Add x y) = RSList [RSAtom "+", fromExpr x, fromExpr y] |