# Julia equivalence of Haskells unfoldr

**URL:** <https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [November 21, 2018, 9:52pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834 "2018-11-21T21:52:59Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [November 21, 2018, 9:53pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/1 "2018-11-21T21:53:00Z")

</div>

Might be a stupid question but I know julia has the `foldl` and `foldr` functions but I cannot find the unfold versions. For example in Haskell we have the `unfoldr` function which produces a list based on an initial value. Does julia have an equivalent function for this? I tried searching for it but nothing useful came up.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 22, 2018, 8:25am UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/2 "2018-11-22T08:25:31Z")

</div>

Since it that is very close to the iterator protocol, you can just do

```julia
struct UnfoldingIterator{T,F}
    init::T
    f::F
end

Base.iterate(uf::UnfoldingIterator) = uf.init, uf.init

function Base.iterate(uf::UnfoldingIterator, state)
    maybestate = uf.f(state)
    if maybestate ≡ nothing
        nothing
    else
        state = something(maybestate)
        state, state
    end
end

Base.IteratorSize(::Type{<:UnfoldingIterator}) = Base.SizeUnknown()

Base.IteratorEltype(::Type{<:UnfoldingIterator}) = Base.EltypeUnknown()

```

then

```julia
julia> collect(UnfoldingIterator(10, x -> x == 0 ? nothing : Some(x-1)))
11-element Array{Int64,1}:
 10
  9
  8
  7
  6
  5
  4
  3
  2
  1
  0

```

---

<div class="post-metadata">

**Author:** ![DoktorMike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/doktormike/32/2736_2.png) [@DoktorMike](https://discourse.julialang.org/u/DoktorMike)\
**Post date:** [November 22, 2018, 8:54am UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/3 "2018-11-22T08:54:22Z")

</div>

Cool and indeed it is. Maybe it’s worth making a Functional.jl containing this. I quite like the functional programming approach. Do you know if it’s a conscious decision to not have it in base as foldl and reduce are there?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 22, 2018, 8:58am UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/4 "2018-11-22T08:58:42Z")

</div>

I don’t really know. I can make a PR to IterTools.jl.

---

<div class="post-metadata">

**Author:** ![idontgetoutmuch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/idontgetoutmuch/32/321_2.png) [@idontgetoutmuch](https://discourse.julialang.org/u/idontgetoutmuch)\
**Post date:** [March 13, 2021, 1:07pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/5 "2021-03-13T13:07:48Z")

</div>

I am guessing this didn’t happen?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 13, 2021, 2:25pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/6 "2021-03-13T14:25:27Z")

</div>

It’s pretty similar to the [`accumulate` function](https://docs.julialang.org/en/v1/base/arrays/#Base.accumulate), no?

---

<div class="post-metadata">

**Author:** ![idontgetoutmuch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/idontgetoutmuch/32/321_2.png) [@idontgetoutmuch](https://discourse.julialang.org/u/idontgetoutmuch)\
**Post date:** [March 13, 2021, 2:43pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/7 "2021-03-13T14:43:55Z")

</div>

I don’t think so but I am a julia noob. A fold takes a list and squashes it down to something; an unfold takes a something and creates a list. Here’s an example of taking an integer and creating a binary representation and a list of 0s and 1s.

```julia
extractBinDigits :: Int -> [Int]
extractBinDigits =
  unfoldr (\x -> if x == 0 then Nothing else Just (mod x 2, div x 2))

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [March 13, 2021, 2:45pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/8 "2021-03-13T14:45:48Z")

</div>

uh, no? `accumulate` applies a binary operator to an already existing list, and return a list of the same size. `unfoldr` applies an unary operator to any value (not only lists) and return a list of unknown size (potentially infinite).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 13, 2021, 4:39pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/9 "2021-03-13T16:39:02Z")

</div>

> [@idontgetoutmuch](#):
>
> A fold takes a list and squashes it down to something; an unfold takes a something and creates a list.

Ah, thanks, sorry for the confusion.

---

<div class="post-metadata">

**Author:** ![idontgetoutmuch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/idontgetoutmuch/32/321_2.png) [@idontgetoutmuch](https://discourse.julialang.org/u/idontgetoutmuch)\
**Post date:** [March 13, 2021, 6:41pm UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/10 "2021-03-13T18:41:53Z")

</div>

Thank you for taking the time 😀

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 14, 2021, 8:37am UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/11 "2021-03-14T08:37:34Z")

</div>

No, I didn’t make the PR, but if my solution works for you, feel free to use the code for the purposes of a PR.

---

<div class="post-metadata">

**Author:** ![ColinCaine](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/colincaine/32/7211_2.png) [@ColinCaine](https://discourse.julialang.org/u/ColinCaine)\
**Post date:** [November 24, 2021, 10:57am UTC](https://discourse.julialang.org/t/julia-equivalence-of-haskells-unfoldr/17834/12 "2021-11-24T10:57:13Z")

</div>

Made a PR for this that arguably improves on the definition a bit: [https://github.com/JuliaLang/julia/pull/43203](https://github.com/JuliaLang/julia/pull/43203)
