Last active
December 18, 2015 01:29
-
-
Save dtchepak/5704277 to your computer and use it in GitHub Desktop.
My attempt at first 4 or so steps of string calc kata, using Parsec. Not strictly following the kata requirements, just experimenting.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- LANGUAGE OverloadedStrings -} | |
import Control.Applicative ((<*)) | |
import Data.Functor ((<$)) | |
import Data.Text (Text) | |
import Text.Parsec | |
import Text.Parsec.Text (GenParser) | |
type Parser = GenParser () | |
defaultDelim :: Parser Char | |
defaultDelim = newline <|> char ',' -- <|> is "or". default delimiter is newline or comma | |
customDelim :: Parser (Parser Char) | |
customDelim = do | |
count 2 (char '/') | |
delim <- anyChar | |
newline | |
return $ char delim | |
stringCalcP :: Parser [Int] | |
stringCalcP = do | |
delim <- customDelim <|> return defaultDelim -- Look for custom delim, or use default delim parser. | |
empty <|> positive `sepBy` delim -- Empty or delimited list of positive ints | |
add :: Text -> Maybe Int | |
add = parseAll $ fmap sum stringCalcP | |
-------------------- | |
-- Helpers | |
-- Not sure if these are already in Parsec somewhere. | |
empty :: Parser [a] | |
empty = [] <$ eof | |
positive :: Parser Int | |
positive = read `fmap` many1 digit | |
parseAll :: Parser a -> Text -> Maybe a | |
parseAll p s = | |
let parseToEnd = p <* eof -- matches p then eof, but only returns value from p | |
parsed = parse parseToEnd [] s | |
in either (const Nothing) Just parsed | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment