# Is there a strict \`Endo\`?

**URL:** <https://discourse.haskell.org/t/is-there-a-strict-endo/8441>\
**Category:** Learn\
**Created:** [January 1, 2024, 2:55pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441 "2024-01-01T14:55:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [January 1, 2024, 2:55pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/1 "2024-01-01T14:55:40Z")

</div>

`base` [has](https://hackage.haskell.org/package/base-4.19.0.0/docs/Data-Monoid.html#t:Endo) (essentially)

```haskell
newtype Endo a = Endo (a -> a)

Endo f <> Endo g = Endo (f . g)

```

But is there a strict equivalent? That is, something that does

```haskell
newtype StrictEndo a = StrictEndo (a -> a)

StrictEndo f <> StrictEndo g = StrictEndo (\a -> f $! g a)

```

I don’t recall seeing it. (I also realize that I’ve never seen strict composition, although it does exist in “[`pointless-fun`](https://hackage.haskell.org/package/pointless-fun-1.1.0.8/docs/Data-Function-Pointless.html#v:.-33-)”.)

---

<div class="post-metadata">

**Author:** ![TeofilC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/teofilc/32/3987_2.png) [@TeofilC](https://discourse.haskell.org/u/TeofilC)\
**Post date:** [January 2, 2024, 1:09pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/2 "2024-01-02T13:09:57Z")

</div>

I feel like it’s worth considering why you want a strict `Endo` in the first place. I feel like that will help determine what it should look like. With something like this, there are a surprising amount of candidates for a strict version.

The definition you gave makes sure that the function that is constructed is strict, and additionally is also strict in intermediary results.

Another possibility in that vein is something like:

```haskell
newtype StrictEndo' a = StrictEndo' (a -> a)

runStrictEndo' :: StrictEndo' a -> a -> a
runStrictEndo' (StrictEndo' f) !x = f x

StrictEndo' f <> StrictEndo' g = StrictEndo' (f . g)

```

This variant would create a function that is only strict in the initial argument.

Yet another possibility is something like this:

```haskell
newtype StrictEndo'' a = StrictEndo'' (a -> a)

StrictEndo'' !f <> StrictEndo'' !g = StrictEndo'' (f . g)

```

While this doesn’t necessarily construct a strict function, it does ensure that the constituent functions are evaluated to whnf.

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [January 2, 2024, 1:33pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/3 "2024-01-02T13:33:23Z")

</div>

I don’t actually want it, per se, but I do want to refer to it in an article I’m writing about folds. You’re right: its purpose determines what its implementation should be. In this case, its purpose is to define `foldl'` in terms of `foldr`. `foldl` can be defined in terms of `foldr` as

```haskell
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z

```

and that is, in fact, its [implementation in `base`](https://www.stackage.org/haddock/lts-22.4/base-4.18.1.0/src/Data.Foldable.html#foldl). Unless I’m much mistaken, `foldl'` can be implemented as

```haskell
foldl' f z t = appStrictEndo (getDual (foldMap (Dual . StrictEndo . flip f) t)) z

```

Regarding the other candidates, I’m not sure `StrictEndo'` is particularly useful, because `runStrictEndo' s x` is just `appEndo s $! x`. You can get its behaviour just from `Endo`.

~~By contrast, I don’t think `StrictEndo''` does anything at all. The field of a `newtype` is already strict. But even if it was a `data` type and not a `newtype`, you could recover its behaviour from `Endo` by using `Endo $! f` in place of `StrictEndo'' f`.~~ EDIT: This was nonsense.

---

<div class="post-metadata">

**Author:** ![TeofilC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/teofilc/32/3987_2.png) [@TeofilC](https://discourse.haskell.org/u/TeofilC)\
**Post date:** [January 2, 2024, 1:59pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/4 "2024-01-02T13:59:19Z")

</div>

Ah I see that sounds right to me as well, though I haven’t looked at it in detail.

FWIW `StrictEndo` and `StrictEndo''` will differ in cases such as:

```haskell
evaluate $ (StrictEndo'' (const [])) <> (StrictEndo'' undefined)

```

Stuff like this is admittedly niche though, but might have space usage implications when using `StrictEndo''` as a builder.

But yeah you can enforce a lot of these things manually by using `seq`, etc manually.

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [January 2, 2024, 2:10pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/5 "2024-01-02T14:10:21Z")

</div>

Sorry, I made a couple of typos/thinkos in my final paragraph and I’ve just corrected them. What I meant to say was that `StrictEndo''` doesn’t differ from `Endo`.

---

<div class="post-metadata">

**Author:** ![TeofilC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/teofilc/32/3987_2.png) [@TeofilC](https://discourse.haskell.org/u/TeofilC)\
**Post date:** [January 2, 2024, 2:14pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/6 "2024-01-02T14:14:14Z")

</div>

No worries. I think the example I gave should differentiate between `Endo` and `StrictEndo''` too.  
Here’s a GHCi log:

```haskell
GHCi, version 9.8.1: https://www.haskell.org/ghc/ :? for help
ghci> newtype StrictEndo'' a = StrictEndo'' (a -> a)
ghci> instance Semigroup (StrictEndo'' a) where (StrictEndo'' !f) <> (StrictEndo'' !g) = StrictEndo'' (f . g)
ghci> import Data.Monoid
ghci> import Control.Exception
ghci> evaluate $ (StrictEndo'' (const [])) <> (StrictEndo'' undefined)
*** Exception: Prelude.undefined
CallStack (from HasCallStack):
  undefined, called at <interactive>:6:55 in interactive:Ghci5
ghci> evaluate $ (Endo (const [])) <> (Endo undefined)
ghci>
ghci> evaluate $ (Endo $! (const [])) <> (Endo $! undefined)
ghci>

```

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [January 2, 2024, 2:22pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/7 "2024-01-02T14:22:28Z")

</div>

Ah yes, thanks. I got confused about what it means to bang a field of a `newtype` pattern match.

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [January 2, 2024, 4:37pm UTC](https://discourse.haskell.org/t/is-there-a-strict-endo/8441/8 "2024-01-02T16:37:04Z")

</div>

Interestingly `lens` uses `Endo (Endo s)` rather than `Dual (StrictEndo s)`: [Control.Lens.Combinators](https://www.stackage.org/haddock/lts-22.4/lens-5.2.3/Control-Lens-Combinators.html#v:foldlOf-39-)
