# Module design: When to use a pipeline and when to fold a list?

**URL:** <https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347>\
**Category:** Learn\
**Created:** [March 19, 2019, 6:36am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347 "2019-03-19T06:36:37Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon5324703](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@anon5324703](https://discourse.elm-lang.org/u/anon5324703)\
**Post date:** [March 19, 2019, 6:36am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/1 "2019-03-19T06:36:37Z")

</div>

From the package documentation of `List`:

[foldl](https://package.elm-lang.org/packages/elm/core/latest/List#foldl) : (a -\> b -\> b) -\> b -\> List a -\> b

Reduce a list from the left.

```auto
foldl (+) 0 [1,2,3] == 6
foldl (::) [] [1,2,3] == [3,2,1]

```

So `foldl step state [1,2,3]` is like saying:

```auto
state
  |> step 1
  |> step 2
  |> step 3

```

[foldr](https://package.elm-lang.org/packages/elm/core/latest/List#foldr) : (a -\> b -\> b) -\> b -\> List a -\> b

Reduce a list from the right.

```auto
foldr (+) 0 [1,2,3] == 6
foldr (::) [] [1,2,3] == [1,2,3]

```

So `foldr step state [1,2,3]` is like saying:

```auto
state
  |> step 3
  |> step 2
  |> step 1

```

&nbsp;&nbsp;

So I was wondering, from a design perspective, when is it better to have the user of an API plug a list into some wrapper for `foldl`, and when is it better to have them use a pipeline like `json-decode-pipeline`?

Thanks

---

<div class="post-metadata">

**Author:** ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)\
**Post date:** [March 19, 2019, 6:52am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/2 "2019-03-19T06:52:46Z")

</div>

With a `foldl`/`foldr` the `step` function is `a -> b -> b`.  
With the pipeline the step function is `a -> b -> c`.

In other words, in the fold case the type of the last argument is the type of the return. In the pipe approach, it can be something else. Usually it is something that can take the first argument and produce the return.

---

<div class="post-metadata">

**Author:** ![anon5324703](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@anon5324703](https://discourse.elm-lang.org/u/anon5324703)\
**Post date:** [March 19, 2019, 7:20am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/4 "2019-03-19T07:20:33Z")

</div>

Thanks for the reply!

Sorry for not being clearer—the main thing I wonder is, in the case that either implementation is equivalent, which design would a user prefer?

---

<div class="post-metadata">

**Author:** ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)\
**Post date:** [March 19, 2019, 8:37am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/5 "2019-03-19T08:37:26Z")

</div>

> [@anon5324703](#):
>
> in the case that either implementation is equivalent, which design would a user prefer?

If I can express something as a fold I will always express it as a fold.

Maybe there is something I miss here. If you can give a realistic example I (or someone else) could provide more insight.

---

<div class="post-metadata">

**Author:** ![Herteby](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/herteby/32/1329_2.png) [@Herteby](https://discourse.elm-lang.org/u/Herteby)\
**Post date:** [March 19, 2019, 12:54pm UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/6 "2019-03-19T12:54:34Z")

</div>

Something like this? [https://ellie-app.com/4TV3pTrBjZYa1](https://ellie-app.com/4TV3pTrBjZYa1)

Would you prefer:

```elm
test : Something
test =
    default
        |> field1 "foo"
        |> field2 5
        |> field3 0.5

```

or:

```elm
test2 : Something
test2 =
    build
        [ field1 "foo"
        , field2 5
        , field3 0.5
        ]

```

---

<div class="post-metadata">

**Author:** ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)\
**Post date:** [March 19, 2019, 1:17pm UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/7 "2019-03-19T13:17:29Z")

</div>

> [@Herteby](#):
>
> Something like this? [https://ellie-app.com/4TV3pTrBjZYa1](https://ellie-app.com/4TV3pTrBjZYa1)

This is a very good example as it illustrates the conflict very well.

I have a slight preference for the pipeline version in this case because the “things” are heterogeneous but this is only a slight preference as my mind cannot ignore the fact that `Something` is a record and that I would always write that using Elm syntax.

```elm
test : Something
test =
    { default
        | field1 = "foo"
        , field2 = 5
        , field3 = 0.5
    }

```

Later edit, if you want to mimic the `elm/html` API, you could go for the list version.

```elm

type alias Options = 
    { foo : String 
    , bar : Int 
    }

type alias Attr = Options -> Options 

foo : String -> Attr 
foo theFoo options = 
     { options | foo = theFoo } 

apiEndpoint : List (Attr) -> SomeResult 
apiEndpoint attrs = 
    let 
        options = List.fold identity defaultOptions attrs 
    in 
    ...

```

---

<div class="post-metadata">

**Author:** ![anon5324703](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@anon5324703](https://discourse.elm-lang.org/u/anon5324703)\
**Post date:** [March 20, 2019, 4:21am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/8 "2019-03-20T04:21:35Z")

</div>

Thanks for the example @Herteby, it seems like exactly what I’m interested in.

One thing I notice is that the pipeline exposes the `default`, which might be e g. an empty structure. The `field`s build it up in incremental steps. This approach seems pretty intuitive to me.

In the `List` implementation, the user offers an order, but that may not be the actual order the operations are applied, in case some sequences are less efficient or illegal, they can be rearranged behind the scenes. Additionally, the syntax seems more convenient if all the `step`s are the same. And the user can do convenient operations to this `List`, like mapping, before it’s sent through the api endpoint `build`.

Does anyone else have any thoughts on this or other things they notice?

---

<div class="post-metadata">

**Author:** ![anon5324703](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@anon5324703](https://discourse.elm-lang.org/u/anon5324703)\
**Post date:** [March 20, 2019, 4:28am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/9 "2019-03-20T04:28:32Z")

</div>

> If I can express something as a fold I will always express it as a fold

Why is that? Are there more alternatives, other than folding and a pipeline, that I haven’t considered?

---

<div class="post-metadata">

**Author:** ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)\
**Post date:** [March 20, 2019, 8:09am UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/10 "2019-03-20T08:09:54Z")

</div>

> [@anon5324703](#):
>
> Why is that?

Code is a liability and the semantics of fold are very clear to me. If I can get by writing less function code and reuse one of the already defined functions, I will do that. In any case, this is a heuristic. Of course I break my own rules when I see better alternatives but these better alternatives arise from the specifics of the types involved.

> [@anon5324703](#):
>
> Are there more alternatives, other than folding and a pipeline, that I haven’t considered?

Just look at the API of the libraries hosted on the [elm organization](https://github.com/elm). Read Evan’s [Design Process](https://elm-lang.org/blog/working-with-files#design-process).

---

<div class="post-metadata">

**Author:** ![anon5324703](https://avatars.discourse-cdn.com/v4/letter/a/97f17d/32.png) [@anon5324703](https://discourse.elm-lang.org/u/anon5324703)\
**Post date:** [March 20, 2019, 12:25pm UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/11 "2019-03-20T12:25:49Z")

</div>

Great response, really appreciate the references! I’m definitely persuaded with the principle of consistent semantics.

Can you give an example of something I should look for in those links?

Cheers

---

<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:** [March 30, 2019, 12:26pm UTC](https://discourse.elm-lang.org/t/module-design-when-to-use-a-pipeline-and-when-to-fold-a-list/3347/12 "2019-03-30T12:26:02Z")

</div>

Closed on March 30, 2019, 12:26pm UTC

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