From d5109a50c7da3b74eb2b9b6ed44ef25ad2f6bdf3 Mon Sep 17 00:00:00 2001 From: Takafumi Arakaki Date: Sat, 22 Aug 2020 20:03:22 -0700 Subject: [PATCH] Document more examples (#8) This patch also fixes a bug in `@fgenerator function` with arguments with type bounds. --- README.md | 36 ++++++++++++++++++++++++++++++++++-- docs/src/index.md | 1 + src/FGenerators.jl | 23 +++++++++++++++++++++++ test/test_samples.jl | 15 +++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bbaeae7..3aab6ed 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ [![GitHub Actions](https://github.com/JuliaFolds//FGenerators.jl/workflows/Run%20tests/badge.svg)](https://github.com/JuliaFolds//FGenerators.jl/actions?query=workflow%3ARun+tests) FGenerators.jl is a package for defining Transducers.jl-compatible -extended `foldl` with a simple `@yield`-based syntax. An example for -creating an ad-hoc "generator": +extended `foldl` with a simple `@yield`-based syntax. Here are a few +examples for creating ad-hoc "generators": ```julia julia> using FGenerators @@ -24,6 +24,38 @@ julia> collect(generate123()) julia> sum(generate123()) 6 + +julia> @fgenerator function organpipe(n::Integer) + i = 0 + while i != n + i += 1 + @yield i + end + while true + i -= 1 + i == 0 && return + @yield i + end + end; + +julia> collect(organpipe(3)) +5-element Array{Int64,1}: + 1 + 2 + 3 + 2 + 1 + +julia> @fgenerator function organpipe2(n) + @yieldfrom 1:n + @yieldfrom n-1:-1:1 + end; + +julia> collect(organpipe2(2)) +3-element Array{Int64,1}: + 1 + 2 + 1 ``` FGenerators.jl is a spin-off of diff --git a/docs/src/index.md b/docs/src/index.md index 5cee5fa..829361e 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -7,4 +7,5 @@ FGenerators FGenerators.@fgenerator FGenerators.@yield +FGenerators.@yieldfrom ``` diff --git a/src/FGenerators.jl b/src/FGenerators.jl index 9103d09..687cc25 100644 --- a/src/FGenerators.jl +++ b/src/FGenerators.jl @@ -54,6 +54,27 @@ end """ @yieldfrom foldable + +Yield items from a `foldable`. This is usable only inside special +contexts such as within [`@fgenerator`](@ref) macro. + +## Examples + +```jldoctest @yieldfrom +julia> using FGenerators + +julia> @fgenerator function flatten2(xs, ys) + @yieldfrom xs + @yieldfrom ys + end; + +julia> collect(flatten2(1:2, 11:12)) +4-element Array{Int64,1}: + 1 + 2 + 11 + 12 +``` """ macro yieldfrom(args...) _, on_yieldfrom = YIELD_DEF[] @@ -196,6 +217,8 @@ macro fgenerator(ex) allargs = map([def[:args]; def[:kwargs]]) do x if @capture(x, args_...) args + elseif @capture(x, a_::T_) + a::Symbol else x::Symbol end diff --git a/test/test_samples.jl b/test/test_samples.jl index 37481b9..74e052c 100644 --- a/test/test_samples.jl +++ b/test/test_samples.jl @@ -12,6 +12,19 @@ using Transducers: Map @yield 3 end +@fgenerator function organpipe(n::Integer) + i = 0 + while i != n + i += 1 + @yield i + end + while true + i -= 1 + i == 0 && return + @yield i + end +end + @fgenerator function flatten2(a, b) @yieldfrom a @yieldfrom b @@ -57,6 +70,8 @@ raw_testdata = """ noone() == [] oneone() == [1] onetwothree() == [1, 2, 3] +organpipe(2) == [1, 2, 1] +organpipe(3) == [1, 2, 3, 2, 1] flatten2((1, 2), (3,)) == [1, 2, 3] Count(0, 2) == [0, 1, 2] Count(0, -1) == Int[]