Writing reducibles · Transducers.jl describes how to make a non-iterable collection reducible; e.g. how to use it as input to transducers. But it does not describe how to delegate the reducing operation to another reducible
.
MWE is:
A
and B
are structs and A
contains B
:
struct B
arr::Vector{Int}
end
struct A
b::B
end
a = A(B([1,2,3,3]))
Then I try to make A
and B
reducible, such that:
- folding over
A
should just fold over theB
insideA
, and - folding over
B
should just fold over the array inB
.
i.e. foldl(op, a) == foldl(op, a.b) == foldl(op, a.b.arr)
for some op
.
using Transducers
function Transducers.__foldl__(rf, init, a::A)
init = foldl(rf, a.b |> Transducers.IdentityTransducer(); init)
return Transducers.complete(rf, init)
end
function Transducers.__foldl__(rf, init, b::B)
init = foldl(rf, b.arr; init)
return Transducers.complete(rf, init)
end
And then:
a.b |> Map(string) |> collect # works
a |> Map(string) |> collect # works
a.b |> Map(string) |> Unique() |> collect # works
a |> Map(string) |> Unique() |> collect # FAILS?!
It seems that when using Unique()
it packs some private state that makes the whole thing go down in flames…
So how should I write my __foldl__
to avoid this? Without resorting to the iterator-based @next
pattern…