# \[elm/parser\]: understanding what's going on

**URL:** https://discourse.elm-lang.org/t/elm-parser-understanding-whats-going-on/4153
**Category:** Learn
**Created:** [August 13, 2019, 8:54am UTC](https://discourse.elm-lang.org/t/elm-parser-understanding-whats-going-on/4153 "2019-08-13T08:54:37Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![sfinnie](https://avatars.discourse-cdn.com/v4/letter/s/e79b87/32.png) [@sfinnie](https://discourse.elm-lang.org/u/sfinnie)
#### Post date: [August 13, 2019, 8:54am UTC](https://discourse.elm-lang.org/t/elm-parser-understanding-whats-going-on/4153/1 "2019-08-13T08:54:38Z")

</div>

First off, apologies for length of this question.

I’m having a problem writing parser functions, and it’s exposed a limitation in my understanding of how they work. So, first order, I’d appreciate any help resolving this specific problem. Second order though, any insight into how to think about parser operation more generally would be much appreciated.

**Specific Problem**

I need to handle attribute declarations, for which there are two variants:

1. `name: Type`
2. `name: Type = initialValue`

I followed the [pattern in this post](https://discourse.elm-lang.org/t/elm-parser-how-to-handle-optional-with-default-scenario/4080) to come up with the following:

```
type alias Attribute =
    { name : String
    , type_ : String
    , value : Maybe String
    }

attributeParser : Parser Attribute
attributeParser =
    Parser.succeed identity
        |= parseLowerCaseName
        |. Parser.spaces
        |. Parser.symbol ":"
        |. Parser.spaces
        |= parseUpperCaseName
        |> Parser.andThen attributeInitialValueParser

attributeInitialValueParser : String -> String -> Parser Attribute
attributeInitialValueParser name type_ =
    Parser.oneOf
        [ Parser.succeed (Attribute name type_)
            |. Parser.spaces
            |. Parser.symbol "="
            |. Parser.spaces
            |= (Parser.map Just parseValue)
        , Parser.succeed (Attribute name type_ Nothing)
        ]

```

That doesn’t type check. Intuitively, I think it’s because `attributeParser` is pushing 2 values into the pipe (the parsed name & type), but (1) that’s not compatible with `Parser.succeed identity` and (2) I’m not convinced the type signature for `attributeInitialValueParser` is correct. Perhaps it should take a tuple `(String, String)` instead of two separate params?

Any help on that appreciated. Thanks.

**General Problem**

Hitting this highlighted I don’t understand the parsing mechanism as well as I thought I did. I read through the source, but it’s quite abstract and I’ll admit was a bit of a challenge for an elm newbie. So I don’t feel that much better placed. Intuitively, I understand that the pipeline functions (notably `|=` & `|.`) facilitate combination. When run, the input string is passed to each Parser function. Those functions do one or both of the following:

- Consume characters from the input stream
- Add parsed elements to the “output stream” (recognising this isn’t really a stream).

However I don’t yet have a good mental model for how to think about this more formally. For example: the compiler error on the code above says:

```
The 1st argument to `andThen` is not what I expect:

101| |> Parser.andThen attributeInitialValueParser
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
This `attributeInitialValueParser` value is a:

    String -> Parser b

But `andThen` needs the 1st argument to be:

    String -> Parser Attribute

```

But the type signature for `attributeInitialValueParser` is `String -> String -> Parser Attribute`.

This is already quite long so I’ll stop here. Any insight appreciated.

Thanks.

---

<div class="post-metadata">

### Author: ![dmy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dmy/32/702_2.png) [@dmy](https://discourse.elm-lang.org/u/dmy)
#### Post date: [August 13, 2019, 10:10am UTC](https://discourse.elm-lang.org/t/elm-parser-understanding-whats-going-on/4153/2 "2019-08-13T10:10:53Z")

</div>

> [@sfinnie](#):
>
> Perhaps it should take a tuple `(String, String)` instead of two separate params?

Your intuition was good.

Check the signatures of `identity` and `Parser.andThen`:

```auto
identity: a -> a
andThen : (a -> Parser b) -> Parser a -> Parser b

```

Both `identity` and the fist parameter of `andThen`, which is a function, use a single argument.

But in `attributeParser`, `identity` will receive two arguments (ignoring the details of currying for a moment), as there are two `|=` in the pipeline, and the result will be passed to `attributeInitialValueParser`. This won’t work.

You could use:

```auto
attributeParser : Parser Attribute
attributeParser =
    Parser.succeed Tuple.pair
    ...

```

then

```auto
attributeInitialValueParser : (String, String) -> Parser Attribute
attributeInitialValueParser (name, type_) =

```

This way, you have a single value in the first part, a tuple, passed to the second part.

---

<div class="post-metadata">

### Author: ![sfinnie](https://avatars.discourse-cdn.com/v4/letter/s/e79b87/32.png) [@sfinnie](https://discourse.elm-lang.org/u/sfinnie)
#### Post date: [August 13, 2019, 11:58am UTC](https://discourse.elm-lang.org/t/elm-parser-understanding-whats-going-on/4153/3 "2019-08-13T11:58:01Z")

</div>

@dmy thanks for your help once again.

Reflecting on your response and trying to answer the second part of my question then in very rudeimentary terms:

- The first line in the parser implementation sets the “shape” of what will be captured if the parser succeeds.
- So `succeed Tuple.pair` says the sequence of parsing actions will generate a pair of values, whereas `succeed identity` says only a single value will be captured
- More formally, `Tuple.pair` is a constructor function that takes 2 parameters and returns a tuple. (Its type signature is `a -> b -> (a, b)`. Whereas the type of `identity` is `a -> a` - so it only consumes a single value (and returns it).

I’ll think more about the values being passed to `andThen` so I’m clear how it’s working. Meantime, thanks again.

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [August 23, 2019, 11:58am UTC](https://discourse.elm-lang.org/t/elm-parser-understanding-whats-going-on/4153/4 "2019-08-23T11:58:03Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
