Skip to content

Instantly share code, notes, and snippets.

@newlandsvalley
Created January 31, 2016 10:34
Show Gist options
  • Save newlandsvalley/96dabd17480609ab4000 to your computer and use it in GitHub Desktop.
Save newlandsvalley/96dabd17480609ab4000 to your computer and use it in GitHub Desktop.
Elm runtime error - caused by mutual recursion?
import Combine exposing (..)
import Combine.Char exposing (..)
import Combine.Infix exposing (..)
import Graphics.Element exposing (..)
{- dependencies
"elm-lang/core": "3.0.0 <= v < 4.0.0",
"Bogdanp/elm-combine": "2.0.0 <= v < 3.0.0"
-}
example = "(AB C D E F)"
{- intended eventual example
example = "(AB (C D) E F)"
-}
type Music
=
Note String
| Rest
| Slur (List Music)
| Spacer Int
spacer : Parser Music
spacer = Spacer <$> ( List.length <$> (many1 space))
note : Parser Music
note = Note <$> regex "[A-G]"
rest : Parser Music
rest = succeed Rest <* regex "[XxZz]"
<?> "rest"
slur : Parser Music
slur = Slur <$> parens (many1 slurContent)
<?> "slur"
slurContent : Parser Music
slurContent = choice
[
note
, slur -- Comment out this line to get rid of the runtime error
, spacer
]
musicLine : Parser (List Music)
musicLine = many musicItem
musicItem : Parser Music
musicItem =
choice
[
note
, rest
, slur
, spacer
]
{-| Compute the result of an expression. -}
music : String -> Result String (List Music)
music s =
case parse (musicLine <* end) s of
(Ok n, _) ->
Ok n
(Err ms, cx) ->
Err ("parse error: " ++ (toString ms) ++ ", " ++ (toString cx))
main : Element
main = show (music example)
@newlandsvalley
Copy link
Author

Known problem because elm is greedy rather than lazy. Hence, elm-combine's rec() function which defers a parser's evaluation and which should thus be used on any mutually recursive calls.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment