Skip to content

Commit 0c7525e

Browse files
authored
- Add one argument ``curried'' forms of `isequal`, `==` and `in`. - Keep the following definitions to not break Compat on julia v0.6: - const EqualTo{T} = Fix2{typeof(isequal),T} - equalto(x) = isequal(x) - const OccursIn{T} = Fix2{typeof(in),T} - occursin(x) = in(x)
1 parent b43c216 commit 0c7525e

File tree

3 files changed

+96
-65
lines changed

3 files changed

+96
-65
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,8 @@ Currently, the `@compat` macro supports the following syntaxes:
233233
`cov(::AbstractVector; corrected=)` and `cov(::AbstractVector, ::AbstractVector; corrected=)`
234234
are only available on 0.6. ([#21709])
235235

236-
* `equalto` constructs an `EqualTo` object that can be used as a predicate ([#23812]).
236+
* `isequal`, `==` and `in` have one argument "curried" forms. For example `isequal(x)`
237+
returns a function that compares its arguments to `x` using `isequal` ([#26436]).
237238

238239
* `*(::Union{Char,AbstractString},::Union{Char,AbstractString})` concatenation. ([#22512])
239240

@@ -350,18 +351,18 @@ Currently, the `@compat` macro supports the following syntaxes:
350351
* `find` is now `findall` ([#25545]).
351352

352353
* `search` is now `findfirst`/`findnext` and `rsearch` is now `findlast`/`findprev`,
353-
sometimes combined with `equalto` or `occursin` ([#24673]).
354+
sometimes combined with `isequal` or `in` ([#24673], [#26436]).
354355

355356
* `Compat.findfirst`, `Compat.findnext`, `Compat.findlast` and `Compat.findprev`,
356357
return `nothing` when no match is found (rather than `0` or `0:-1`)
357358
as on Julia 0.7 ([#24673], [#26149]).
358359

359-
* `findin(a, b)` is now `findall(occursin(b), a)` ([#24673]).
360+
* `findin(a, b)` is now `findall(in(b), a)` ([#24673]).
360361

361362
* `indmin` and `indmax` are now `argmin` and `argmax`, respectively ([#25654]).
362363

363364
* `Compat.indexin` accepts any iterable as first argument, returns `nothing` (rather than `0`)
364-
for entries with no match and gives the index of the first (rather than the last) match
365+
for entries with no match and gives the index of the first (rather than the last) match
365366
([#25662], [#25998]).
366367

367368
* `isabstract` and `isleaftype` are now `isabstracttype` and `isconcretetype`, respectively
@@ -532,7 +533,6 @@ includes this fix. Find the minimum version from there.
532533
[#23642]: https://github.com/JuliaLang/julia/issues/23642
533534
[#23666]: https://github.com/JuliaLang/julia/issues/23666
534535
[#23757]: https://github.com/JuliaLang/julia/issues/23757
535-
[#23812]: https://github.com/JuliaLang/julia/issues/23812
536536
[#23931]: https://github.com/JuliaLang/julia/issues/23931
537537
[#24047]: https://github.com/JuliaLang/julia/issues/24047
538538
[#24182]: https://github.com/JuliaLang/julia/issues/24182
@@ -599,4 +599,5 @@ includes this fix. Find the minimum version from there.
599599
[#26149]: https://github.com/JuliaLang/julia/issues/26149
600600
[#26156]: https://github.com/JuliaLang/julia/issues/26156
601601
[#26316]: https://github.com/JuliaLang/julia/issues/26316
602-
[#26442]: https://github.com/JuliaLang/julia/issues/26442
602+
[#26436]: https://github.com/JuliaLang/julia/issues/26436
603+
[#26442]: https://github.com/JuliaLang/julia/issues/26442

src/Compat.jl

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -868,27 +868,39 @@ else
868868
import Serialization
869869
end
870870

871-
# 0.7.0-DEV.1993
872-
@static if !isdefined(Base, :EqualTo)
873-
if VERSION >= v"0.6.0"
874-
include_string(@__MODULE__, """
875-
struct EqualTo{T} <: Function
876-
x::T
871+
@static if VERSION < v"0.7.0-DEV.4592"
872+
struct Fix2{F,T} <: Function
873+
f::F
874+
x::T
875+
Fix2(f::F, x::T) where {F,T} = new{F,T}(f, x)
876+
Fix2(f::Type{F}, x::T) where {F,T} = new{F,T}(f, x)
877+
end
878+
(f::Fix2)(y) = f.f(y, f.x)
877879

878-
EqualTo(x::T) where {T} = new{T}(x)
879-
end
880-
""")
880+
Base.:(==)(x) = Fix2(==, x)
881+
@static if VERSION >= v"0.7.0-DEV.1993"
882+
Base.isequal(x) = Base.equalto(x)
881883
else
882-
include_string(@__MODULE__, """
883-
immutable EqualTo{T} <: Function
884-
x::T
885-
end
886-
""")
884+
Base.isequal(x) = Fix2(isequal, x)
885+
end
886+
@static if VERSION >= v"0.7.0-DEV.3272"
887+
Base.in(x) = Base.occursin(x)
888+
else
889+
Base.in(x) = Fix2(in, x)
887890
end
888-
(f::EqualTo)(y) = isequal(f.x, y)
889-
const equalto = EqualTo
891+
end
892+
# keep these definitions to be non breaking for 0.6 usage
893+
@static if VERSION < v"0.7.0-DEV.1993"
894+
const EqualTo{T} = Fix2{typeof(isequal),T}
890895
export equalto
896+
equalto(x) = isequal(x)
891897
end
898+
@static if VERSION < v"0.7.0-DEV.3272"
899+
const OccursIn{T} = Fix2{typeof(in),T}
900+
export occursin
901+
occursin(x) = in(x)
902+
end
903+
892904

893905
# 0.7.0-DEV.912
894906
if VERSION < v"0.7.0-DEV.912"
@@ -1486,15 +1498,6 @@ end
14861498
findprev(xs...) = Base.findprev(xs...)
14871499
findlast(xs...) = Base.findlast(xs...)
14881500
else
1489-
struct OccursIn{T} <: Function
1490-
x::T
1491-
1492-
OccursIn(x::T) where {T} = new{T}(x)
1493-
end
1494-
(f::OccursIn)(y) = y in f.x
1495-
const occursin = OccursIn
1496-
export occursin
1497-
14981501
zero2nothing(x::Integer) = x == 0 ? nothing : x
14991502
zero2nothing(x::AbstractUnitRange{<:Integer}) = x == 0:-1 ? nothing : x
15001503
zero2nothing(x) = x
@@ -1506,41 +1509,41 @@ else
15061509

15071510
Base.findnext(r::Regex, s::AbstractString, idx::Integer) = search(s, r, idx)
15081511
Base.findfirst(r::Regex, s::AbstractString) = search(s, r)
1509-
Base.findnext(c::EqualTo{Char}, s::AbstractString, i::Integer) = search(s, c.x, i)
1510-
Base.findfirst(c::EqualTo{Char}, s::AbstractString) = search(s, c.x)
1511-
Base.findnext(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
1512+
Base.findnext(c::Fix2{typeof(isequal),Char}, s::AbstractString, i::Integer) = search(s, c.x, i)
1513+
Base.findfirst(c::Fix2{typeof(isequal),Char}, s::AbstractString) = search(s, c.x)
1514+
Base.findnext(b::Fix2{typeof(isequal),<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
15121515
search(a, b.x, i)
1513-
Base.findfirst(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
1516+
Base.findfirst(b::Fix2{typeof(isequal),<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
15141517
search(a, b.x)
15151518

1516-
Base.findnext(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1519+
Base.findnext(c::Fix2{typeof(in),<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
15171520
s::AbstractString, i::Integer) =
15181521
search(s, c.x, i)
1519-
Base.findfirst(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1522+
Base.findfirst(c::Fix2{typeof(in),<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
15201523
s::AbstractString) =
15211524
search(s, c.x)
15221525
Base.findnext(t::AbstractString, s::AbstractString, i::Integer) = search(s, t, i)
15231526
Base.findfirst(t::AbstractString, s::AbstractString) = search(s, t)
15241527

1525-
Base.findfirst(delim::EqualTo{UInt8}, buf::Base.IOBuffer) = search(buf, delim.x)
1528+
Base.findfirst(delim::Fix2{typeof(isequal),UInt8}, buf::Base.IOBuffer) = search(buf, delim.x)
15261529

1527-
Base.findprev(c::EqualTo{Char}, s::AbstractString, i::Integer) = rsearch(s, c.x, i)
1528-
Base.findlast(c::EqualTo{Char}, s::AbstractString) = rsearch(s, c.x)
1529-
Base.findprev(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
1530+
Base.findprev(c::Fix2{typeof(isequal),Char}, s::AbstractString, i::Integer) = rsearch(s, c.x, i)
1531+
Base.findlast(c::Fix2{typeof(isequal),Char}, s::AbstractString) = rsearch(s, c.x)
1532+
Base.findprev(b::Fix2{typeof(isequal),<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}, i::Integer) =
15301533
rsearch(a, b.x, i)
1531-
Base.findlast(b::EqualTo{<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
1534+
Base.findlast(b::Fix2{typeof(isequal),<:Union{Int8,UInt8}}, a::Vector{<:Union{Int8,UInt8}}) =
15321535
rsearch(a, b.x)
15331536

1534-
Base.findprev(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1537+
Base.findprev(c::Fix2{typeof(in),<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
15351538
s::AbstractString, i::Integer) = rsearch(s, c.x, i)
1536-
Base.findlast(c::OccursIn{<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
1539+
Base.findlast(c::Fix2{typeof(in),<:Union{Tuple{Vararg{Char}},AbstractVector{Char},Set{Char}}},
15371540
s::AbstractString) = rsearch(s, c.x)
15381541
Base.findprev(t::AbstractString, s::AbstractString, i::Integer) = rsearch(s, t, i)
15391542
Base.findlast(t::AbstractString, s::AbstractString) = rsearch(s, t)
15401543

1541-
findall(b::OccursIn, a) = findin(a, b.x)
1544+
findall(b::Fix2{typeof(in)}, a) = findin(a, b.x)
15421545
# To fix ambiguity
1543-
findall(b::OccursIn, a::Number) = a in b.x ? [1] : Vector{Int}()
1546+
findall(b::Fix2{typeof(in)}, a::Number) = a in b.x ? [1] : Vector{Int}()
15441547
end
15451548

15461549
@static if VERSION < v"0.7.0-DEV.4047" #26089

test/runtests.jl

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -947,13 +947,26 @@ module Test24648
947947
end
948948

949949
let a = [0,1,2,3,0,1,2,3]
950-
@test findfirst(equalto(3), [1,2,4,1,2,3,4]) == 6
951-
@test findfirst(!equalto(1), [1,2,4,1,2,3,4]) == 2
952-
@test findnext(equalto(1), a, 4) == 6
953-
# @test findnext(equalto(5), a, 4) == 0
954-
@test findlast(equalto(3), [1,2,4,1,2,3,4]) == 6
955-
@test findprev(equalto(1), a, 4) == 2
956-
@test findprev(equalto(1), a, 8) == 6
950+
# curried isequal
951+
@test findfirst(isequal(3), [1,2,4,1,2,3,4]) == 6
952+
@test findfirst(!isequal(1), [1,2,4,1,2,3,4]) == 2
953+
@test findnext(isequal(1), a, 4) == 6
954+
# @test findnext(isequal(5), a, 4) == 0
955+
@test findlast(isequal(3), [1,2,4,1,2,3,4]) == 6
956+
@test findprev(isequal(1), a, 4) == 2
957+
@test findprev(isequal(1), a, 8) == 6
958+
if VERSION < v"0.7.0-DEV.4592"
959+
# test that equalto work on 0.6
960+
@test findfirst(equalto(3), [1,2,4,1,2,3,4]) == 6
961+
@test findfirst(!equalto(1), [1,2,4,1,2,3,4]) == 2
962+
end
963+
# curried ==
964+
@test findfirst(==(3), [1,2,4,1,2,3,4]) == 6
965+
@test findfirst(!(==(1)), [1,2,4,1,2,3,4]) == 2
966+
@test findnext(==(1), a, 4) == 6
967+
@test findlast(==(3), [1,2,4,1,2,3,4]) == 6
968+
@test findprev(==(1), a, 4) == 2
969+
@test findprev(==(1), a, 8) == 6
957970
end
958971

959972
# 0.7
@@ -1358,24 +1371,34 @@ end
13581371
for (f1, f2, i) in ((Compat.findfirst, Compat.findnext, 1),
13591372
(Compat.findlast, Compat.findprev, 2))
13601373
# Generic methods
1361-
@test f1(equalto(0), [1, 0]) == f2(equalto(0), [1, 0], i) == 2
1362-
@test f1(equalto(9), [1, 0]) == f2(equalto(9), [1, 0], i) == nothing
1363-
@test f1(occursin([0, 2]), [1, 0]) == f2(occursin([0, 2]), [1, 0], i) == 2
1364-
@test f1(occursin([0, 2]), [1, 9]) == f2(occursin([0, 2]), [1, 9], i) == nothing
1374+
@test f1(isequal(0), [1, 0]) == f2(isequal(0), [1, 0], i) == 2
1375+
@test f1(isequal(9), [1, 0]) == f2(isequal(9), [1, 0], i) == nothing
1376+
@test f1(in([0, 2]), [1, 0]) == f2(in([0, 2]), [1, 0], i) == 2
1377+
@test f1(in([0, 2]), [1, 9]) == f2(in([0, 2]), [1, 9], i) == nothing
1378+
if VERSION < v"0.7.0-DEV.4592"
1379+
# test that occursin work on 0.6
1380+
@test f1(occursin([0, 2]), [1, 0]) == f2(occursin([0, 2]), [1, 0], i) == 2
1381+
@test f1(occursin([0, 2]), [1, 9]) == f2(occursin([0, 2]), [1, 9], i) == nothing
1382+
end
13651383
@test f1([true, false]) == f2([true, false], i) == 1
13661384
@test f1([false, false]) == f2([false, false], i) == nothing
13671385

13681386
# Specific methods
1369-
@test f2(equalto('a'), "ba", i) == f1(equalto('a'), "ba") == 2
1387+
@test f2(isequal('a'), "ba", i) == f1(isequal('a'), "ba") == 2
13701388
for S in (Int8, UInt8), T in (Int8, UInt8)
13711389
# Bug in Julia 0.6
13721390
f1 === Compat.findlast && VERSION < v"0.7.0-DEV.3272" && continue
1373-
@test f2(equalto(S(1)), T[0, 1], i) == f1(equalto(S(1)), T[0, 1]) == 2
1374-
@test f2(equalto(S(9)), T[0, 1], i) == f1(equalto(S(9)), T[0, 1]) == nothing
1391+
@test f2(isequal(S(1)), T[0, 1], i) == f1(isequal(S(1)), T[0, 1]) == 2
1392+
@test f2(isequal(S(9)), T[0, 1], i) == f1(isequal(S(9)), T[0, 1]) == nothing
13751393
end
13761394
for chars in (['a', 'z'], Set(['a', 'z']), ('a', 'z'))
1377-
@test f2(occursin(chars), "ba", i) == f1(occursin(chars), "ba") == 2
1378-
@test f2(occursin(chars), "bx", i) == f1(occursin(chars), "bx") == nothing
1395+
@test f2(in(chars), "ba", i) == f1(in(chars), "ba") == 2
1396+
@test f2(in(chars), "bx", i) == f1(in(chars), "bx") == nothing
1397+
if VERSION < v"0.7.0-DEV.4592"
1398+
# test that occursin work on 0.6
1399+
@test f2(occursin(chars), "ba", i) == f1(occursin(chars), "ba") == 2
1400+
@test f2(occursin(chars), "bx", i) == f1(occursin(chars), "bx") == nothing
1401+
end
13791402
end
13801403
end
13811404
@test findnext("a", "ba", 1) == findfirst("a", "ba") == 2:2
@@ -1392,11 +1415,15 @@ end
13921415
@test Compat.findnext(r"a", "ba", 1) == Compat.findfirst(r"a", "ba") == 2:2
13931416
@test Compat.findnext(r"z", "ba", 1) == Compat.findfirst(r"z", "ba") == nothing
13941417

1395-
@test Compat.findfirst(equalto(UInt8(0)), IOBuffer(UInt8[1, 0])) == 2
1396-
@test Compat.findfirst(equalto(UInt8(9)), IOBuffer(UInt8[1, 0])) == nothing
1418+
@test Compat.findfirst(isequal(UInt8(0)), IOBuffer(UInt8[1, 0])) == 2
1419+
@test Compat.findfirst(isequal(UInt8(9)), IOBuffer(UInt8[1, 0])) == nothing
13971420

13981421
@test findall([true, false, true]) == [1, 3]
1399-
@test findall(occursin([1, 2]), [1]) == [1]
1422+
@test findall(in([1, 2]), [1]) == [1]
1423+
if VERSION < v"0.7.0-DEV.4592"
1424+
# test that occursin work on 0.6
1425+
@test findall(occursin([1, 2]), [1]) == [1]
1426+
end
14001427

14011428
# 0.7.0-DEV.3666
14021429
module TestUUIDs

0 commit comments

Comments
 (0)