Skip to content

Instantly share code, notes, and snippets.

@maciejsmolinski
Last active May 25, 2020 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maciejsmolinski/c09a58c0d3101fad4f0fd61ebd3399b5 to your computer and use it in GitHub Desktop.
Save maciejsmolinski/c09a58c0d3101fad4f0fd61ebd3399b5 to your computer and use it in GitHub Desktop.
module Parser (Parser, item, digit, run) where
import Data.Int (fromString)
import Data.Maybe (fromJust, Maybe(..))
import Data.String.CodeUnits (charAt, drop, singleton)
import Data.Tuple (Tuple(..))
import Partial.Unsafe (unsafePartial)
import Prelude
newtype Parser a = Parser (String -> Array (Tuple a String))
item :: Parser Char
item = Parser $ case _ of
"" -> []
string -> [Tuple (unsafePartial $ fromJust $ charAt 0 string) (drop 1 string)]
run :: forall a. Parser a -> String -> Array (Tuple a String)
run (Parser parse) string = parse string
instance functorParser :: Functor Parser where
map :: forall a b. (a -> b) -> Parser a -> Parser b
map f (Parser parse) = Parser $ \string ->
case parse string of
[Tuple a rest] -> [Tuple (f a) rest]
_ -> []
instance applyParser :: Apply Parser where
apply :: forall a b. Parser (a -> b) -> Parser a -> Parser b
apply (Parser f) (Parser parse) = Parser $ \string ->
case f string of
[Tuple fn rest] -> case parse rest of
[Tuple b rest'] -> [Tuple (fn b) rest']
_ -> []
_ -> []
instance monadParser :: Bind Parser where
bind :: forall a b. Parser a -> (a -> Parser b) -> Parser b
bind (Parser parse) f = Parser $ \string ->
case parse string of
[Tuple x remaining] -> case (f x) of
(Parser parse') -> case parse' remaining of
[Tuple x' remaining'] -> [Tuple x' remaining']
_ -> []
_ -> []
success :: forall a. a -> Parser a
success a = Parser \string -> [Tuple a string]
fail :: forall a. Parser a
fail = Parser \string -> []
digit :: Parser Int
digit = do
x <- item
case fromString $ singleton x of
Just num -> success num
Nothing -> fail
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment