Skip to content

Instantly share code, notes, and snippets.

@joonazan
Created April 15, 2017 17:56
Show Gist options
  • Save joonazan/b479b589c22254099cec837d4c1e0816 to your computer and use it in GitHub Desktop.
Save joonazan/b479b589c22254099cec837d4c1e0816 to your computer and use it in GitHub Desktop.
Invalid recursion in Elm 0.18 still causes runtime error
module ParseLibrary exposing (typeSignature)
import Combine exposing (..)
import Dict exposing (Dict)
type Type
= TArrow Type Type
| TName String
| TRecord (Dict String Type)
typeSignature =
lazy (\() ->
sepBy (whitespace *> string "->" *> whitespace) nonFunctionType
|> andThen (\list ->
reducer TArrow list
|> Maybe.map succeed
|> Maybe.withDefault (fail "expected type, got nothing")
)
)
reducer : (a -> a -> a) -> List a -> Maybe a
reducer f list =
case list of
last :: [] ->
Just last
head :: tail ->
reducer f tail
|> Maybe.map (f head)
[] ->
Nothing
nonFunctionType : Parser s Type
nonFunctionType =
lazy <| \() ->
choice
[ typeName
, record
]
typeName : Parser s Type
typeName =
TName <$> uppercaseName
-- TODO: partial record
record : Parser s Type
record =
(TRecord << Dict.fromList) <$> (string "{" *> commaSeparated recordItem <* string "}")
recordItem : Parser a (String, Type)
recordItem =
(,) <$> lowercaseName <* string ":" <* whitespace <*> typeSignature
commaSeparated : Parser s item -> Parser s (List item)
commaSeparated =
sepBy (string ",")
alphanumericRe : String
alphanumericRe = "[A-Za-z0-9]*"
uppercaseName : Parser s String
uppercaseName =
whitespace *> regex ("[A-Z]" ++ alphanumericRe) <* whitespace
lowercaseName : Parser s String
lowercaseName =
whitespace *> regex ("[a-z]" ++ alphanumericRe) <* whitespace
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment