Closed turboMaCk closed 7 years ago
update: I've managed to make example much simpler.
This is same issue reproduced by reducing official Scheme parser example:
module Scheme exposing (..)
import Combine exposing (..)
type E
= EList (List E)
list : Parser s E
list =
EList
<$> parens (many expr)
<?> "list"
expr : Parser s E
expr =
lazy <|
\() ->
whitespace *> list <* whitespace
program : Parser s (List E)
program =
manyTill expr end
parse : String -> Result String (List E)
parse s =
case Combine.parse program s of
Ok ( _, _, e ) ->
Ok e
Err ( _, _, errs ) ->
Err <| String.join " or " errs
code =
"""()"""
res =
parse code
@turboMaCk it would help a lot if you could also describe the error itself, paste it here.
@eeue56 I don't get why it disappeared from original post. I've tried to update but it's keep disappearing on save:(
exception is:
Uncaught TypeError: Cannot read property 'ctor' of undefined
at _elm_community$parser_combinators$Combine$app
compiled code:
var _elm_community$parser_combinators$Combine$app = function (p) {
var _p0 = p;
if (_p0.ctor === 'Parser') {
return _p0._0;
} else {
return _elm_lang$lazy$Lazy$force(_p0._0);
}
};
I was playing with this a bit more and I have failing & fix example.
let me start with broken code (again using simplified Scheme parser)
module Scheme exposing (..)
import Combine exposing (..)
type E
= EList (List E)
| EComment String
comment : Parser s E
comment =
EComment
<$> regex ";[^\n]+"
<?> "comment"
list : Parser s E
list =
EList
<$> parens (many expr)
<?> "list"
expr : Parser s E
expr =
lazy <|
\() ->
let
parsers =
[ list
, comment
]
in
whitespace *> choice parsers <* whitespace
program : Parser s (List E)
program =
manyTill expr end
parse : String -> Result String (List E)
parse s =
case Combine.parse program s of
Ok ( _, _, e ) ->
Ok e
Err ( _, _, errs ) ->
Err <| String.join " or " errs
code =
"""()"""
res =
parse code
this fails in runtime with same exception.
Now you can fix code just by simply changing order of E
constructors:
type E
= EComment String
| EList (List E)
works in repl as expected.
> res
Ok ([EList []]) : Result.Result String (List Scheme.E)
@turboMaCk I've fixed your issue in an Ellie (https://ellie-app.com/x4K8Ly3g9Na1/2)
You added the lazy to the expr
, but it was needed on the list
.
If you have a cyclic reference of combinators. For example: list -> expr -> list
, it is kind of a best practice to define lazy on each of them.
I believe the issue that causes this problem is Elm Compiler #1527.
Hi folks :wave:!
I think I've found bug but also believe this is cased by elm compiler rather that
Combine
itself. Anyway I think it's still good to have a record of this.This is so far the most minimal example I've managed to find:
I've tried to debug deeply but
undefined
value has been past many times so I didn't manage to identify where it actually happens (yet).Hope it all make sense.
update: simpler example