EllipsisNotationForInfiniteList.jl

Run Settings
LanguageJulia
Language Version
Run Command
# runtests.jl include("./dot_dot_list.jl") using DotDotList using Base.Test tests = ["dot_dot_list_test"] if VERSION >= v"0.5.0-dev+5239" push!(tests, "dot_dot_list_v5_test") end for t in tests println("testing $t ...") @time include("$t.jl") end
# dot_dot_list.jl # (1,..) / (1,3,..) Notations for Infinite List # Inspired by: EllipsisNotation.jl (https://github.com/ChrisRackauckas/EllipsisNotation.jl) # 2018/03/28: Fix for Julia v0.6.x or greater module DotDotList import Base.eltype, Base.length, Base.start, Base.done, Base.next, Base.show const DotDot = Val{:..} const .. = DotDot() const DotDotInf1{T} = Tuple{T,DotDot} const DotDotInf2{T} = Tuple{T,T,DotDot} const DotDotInf{T} = Union{DotDotInf1{T}, DotDotInf2{T}} @inline eltype(::DotDotInf{T}) where {T} = T @inline eltype(::Type{DotDotInf1{T}}) where {T} = T @inline eltype(::Type{DotDotInf2{T}}) where {T} = T @inline length(it::DotDotInf{T}) where {T} = typemax(Int) @inline Base.iteratorsize(::DotDotInf{T}) where {T} = Base.IsInfinite() @inline start(it::DotDotInf1{T}) where {T<:Number} = (it[1], one(T)) @inline start(it::DotDotInf1{Char}) = (it[1], 1) @inline start(it::DotDotInf1{Bool}) = (it[1], 1) @inline start(it::DotDotInf2{T}) where {T} = (it[1], it[2]-it[1]) @inline done(::DotDotInf{Int}, ::NTuple{2,Int}) = false @inline done(::DotDotInf{T}, ::NTuple{2,T}) where {T<:Number} = false @inline done(::DotDotInf{T}, ::Tuple{T,Int}) where {T} = false @inline next(::DotDotInf{T}, t::NTuple{2,T}) where {T<:Number} = ((n,s)=t;(n,(n+s,s))) @inline next(::DotDotInf{Char}, t::Tuple{Char,Int}) = ((n,s)=t;(n,(n+s,s))) @inline next(::DotDotInf{Bool}, t::Tuple{Bool,Int}) = ((n,s)=t;(n,((n+s)%Bool,s))) @inline function show(io::IO, it::DotDotInf1{T}) where {T} print(io, '(') show(io, it[1]) print(io, ",..)") end @inline function show(io::IO, it::DotDotInf2{T}) where {T} print(io, '(') show(io, it[1]) print(io, ',') show(io, it[2]) print(io, ",..)") end # Special for DotDotInf2{T<:AbstractFloat} function start(it::DotDotInf2{T}) where {T<:AbstractFloat} if _seemsrational(it[1]) && _seemsrational(it[2]) s = rationalize(it[1]) t = rationalize(it[2]) - s d = convert(T, lcm(denominator(s), denominator(t))) (s*d, t*d, d) else (it[1], it[2] - it[1]) end end @inline done(::DotDotInf{T}, ::NTuple{3,T}) where {T<:AbstractFloat} = false @inline next(::DotDotInf{T}, t::NTuple{3,T}) where {T<:AbstractFloat} = ((n,s,d)=t;(n/d,(n+s,s,d))) @inline _seemsrational(v::T) where {T<:AbstractFloat} = convert(T, rationalize(v)) == v export .., eltype, length, start, done, next, show end # module
# dot_dot_list_test.jl # 2018/03/28: Fix for Julia v0.6.x or greater # include("./dot_dot_list.jl") # using DotDotList # using Base.Test nats = (1,..) # # io = IOBuffer() # # print(io, nats) # # @test "(1,..)" == takebuf_string(io) # v- shorthand of -^ @test "(1,..)" == "$nats" @test Int == eltype(nats) @test [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] == collect(Iterators.take(nats, 10)) odds = (1,3,..) @test "(1,3,..)" == "$odds" @test Int == eltype(odds) @test [1, 3, 5, 7, 9, 11, 13, 15, 17 ,19] == collect(Iterators.take(odds, 10)) issq(n::Int) = isqrt(n)^2 == n @test [1, 9, 25, 49, 81, 121, 169, 225, 289, 361] == collect(Int, Iterators.take(Iterators.filter(issq, odds), 10)) floats = (1.5,..) @test "(1.5,..)" == "$floats" @test Float64 == eltype(floats) @test Float64[1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5] == collect(Iterators.take(floats, 10)) @test 60.0 == sum(Iterators.take(floats, 10)) floats2 = (1.0,1.1,..) @test "(1.0,1.1,..)" == "$floats2" @test Float64 == eltype(floats2) @test Float64[1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0] == collect(Iterators.take(floats2, 11)) @test 16.5 == sum(Iterators.take(floats2, 11)) floats3 = (1.0,4.0/3.0,..) # @test "(1.0,1.3333333333333333,..)" == "$floats3" @test ismatch(r"\(1\.0,1\.33333+,\.\.\)", "$floats3") @test Float64 == eltype(floats3) @test Float64[1.0, 4.0/3.0, 5.0/3.0, 2.0, 7.0/3.0, 8.0/3.0, 3.0, 10.0/3.0, 11.0/3.0, 4.0] == collect(Iterators.take(floats3, 10)) @test 25.0 == sum(Iterators.take(floats3, 10)) rationals = (1//1,9//10,..) @test "(1//1,9//10,..)" == "$rationals" @test Rational{Int} == eltype(rationals) @test Rational{Int}[1//1, 9//10, 4//5, 7//10, 3//5, 1//2, 2//5, 3//10, 1//5, 1//10] == collect(Iterators.take(rationals, 10)) bools1 = (false,..) @test "(false,..)" == "$bools1" @test Bool == eltype(bools1) @test Bool[false, true, false, true, false] == collect(Iterators.take(bools1, 5)) bools2 = (true,false,..) @test "(true,false,..)" == "$bools2" @test Bool == eltype(bools2) @test Bool[true, false, true, false, true] == collect(Iterators.take(bools2, 5)) trues = (true,true,..) @test "(true,true,..)" == "$trues" @test Bool == eltype(trues) @test Bool[true, true, true, true, true] == collect(Iterators.take(trues, 5)) chars = ('A',..) @test "('A',..)" == "$chars" @test Char == eltype(chars) @test Char['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'] == collect(Iterators.take(chars, 10)) odd_chars = ('A','C',..) @test "('A','C',..)" == "$odd_chars" @test Char == eltype(odd_chars) @test Char['A', 'C', 'E', 'G', 'I', 'K', 'M', 'O', 'Q', 'S'] == collect(Iterators.take(odd_chars, 10))
# dot_dot_list_v5_test.jl # 2018/03/28: Fix for Julia v0.6.x or greater # include("./dot_dot_list.jl") # using DotDotList # using Base.Test evens = (2n for n=(1,..)) @test [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] == collect(Int, Iterators.take(evens, 10)) odd_squares = (n^2 for n=(1,3,..)) @test [1, 9, 25, 49, 81, 121, 169, 225, 289, 361] == collect(Int, Iterators.take(odd_squares, 10)) powers = (2^n for n=(1,..)) @test [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] == collect(Int, Iterators.take(powers, 10))
Editor Settings
Theme
Key bindings
Full width
Lines