Skip to content

Commit fcc1fe4

Browse files
Stephan SahmStephan Sahm
authored andcommitted
switched to use Const(nothing) instead of nothing for better consistency and to avoid type-piracy
1 parent 9e55950 commit fcc1fe4

16 files changed

Lines changed: 143 additions & 252 deletions

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ julia = "1.3"
2222

2323
[extras]
2424
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
25+
Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
2526

2627
[targets]
27-
test = ["Test"]
28+
test = ["Test", "Suppressor"]

src/Const.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
"""
2+
Const("anything")
3+
4+
DataType which behaves constant among `map`, `foreach` and the like. Just like an empty container,
5+
however with additional information about which kind of empty.
6+
"""
17
struct Const{T}
28
value::T
39
end
@@ -9,9 +15,16 @@ function Base.show(io::IO, x::Const)
915
print(io, "Const($(repr(x.value)))")
1016
end
1117

12-
isconst(::Const) = true
13-
isconst(other) = false
18+
"""
19+
isconst(Const(3)) -> true
20+
isconst("anythingelse") -> false
21+
22+
returns true only if given an instance of [`DataTypesBasic.Const`](@ref)
23+
"""
24+
Base.isconst(::Const) = true
25+
Base.isconst(other) = false
1426

27+
Base.length(::Const) = 0
1528

1629
# const just does nothing, i.e. leaves everything constant
1730
Base.iterate(c::Const) = nothing

src/DataTypesBasic.jl

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,21 @@ higher code-reuse and datatype-reuse.
3333
"""
3434
module DataTypesBasic
3535

36-
export Const, Identity,
37-
Option, issomething, iftrue, iffalse, getOption, # isnothing, Nothing, Some comes from Base
38-
Either, either, @either, isleft, isright, getleft, getright, getleftOption, getrightOption, flip_left_right,
39-
OptionEither,
36+
export Identity, isidentity, Const,
37+
Option, isoption, iftrue, iffalse, getOption, # isnothing, Nothing, Some comes from Base
38+
Either, either, @either, iseither, isleft, isright, getleft, getright, getleftOption, getrightOption, flip_left_right,
4039
Try, Thrown, @Try, @TryCatch, issuccess, isexception, MultipleExceptions,
4140
ContextManager, @ContextManager
4241

4342
using Compat
4443

4544
# type definitions
46-
include("Nothing.jl")
47-
include("Const.jl")
4845
include("Identity.jl")
46+
include("Const.jl")
4947
include("Option.jl")
5048
include("Try.jl")
5149
include("Either.jl")
5250
include("ContextManager.jl")
53-
include("OptionEither.jl")
5451

5552
# interoperability between types
5653
include("promote_type.jl")

src/Either.jl

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,24 @@ end
3939
flip_left_right(x::Const) = Identity(x.value)
4040
flip_left_right(x::Identity) = Const(x.value)
4141

42-
isleft(e::Const) = true
43-
isleft(e::Identity) = false
42+
iseither(::Const) = true
43+
iseither(::Identity) = true
44+
iseither(other) = false
4445

45-
isright(e::Const) = false
46-
isright(e::Identity) = true
46+
isleft(::Const) = true
47+
isleft(::Identity) = false
48+
49+
isright(::Const) = false
50+
isright(::Identity) = true
4751

4852
getleft(e::Const) = e.value
4953
# getleft(e::Identity) = nothing # throw an error if getleft is called on Identity
5054

5155
# getright(e::Const) = nothing # throw an error if getright is called on Const
5256
getright(e::Identity) = e.value
5357

54-
getleftOption(e::Const{L}) where {L} = Identity{L}(e.value)
55-
getleftOption(e::Identity) = nothing
58+
getleftOption(e::Const) = Option(e.value)
59+
getleftOption(e::Identity) = Option()
5660

57-
getrightOption(e::Const) = nothing
58-
getrightOption(e::Identity{R}) where {R} = e
61+
getrightOption(e::Const) = Option()
62+
getrightOption(e::Identity) = e

src/Identity.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ end
1111
isidentity(::Identity) = true
1212
isidentity(other) = false
1313

14+
Base.length(::Identity) = 1
1415

1516
Base.get(a::Identity) = a.value
1617
Base.eltype(::Type{<:Identity{T}}) where T = T

src/Nothing.jl

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/Option.jl

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,34 @@
11
# we don't use Some because it does not behave like a container, but more like `Ref`
22
# for details/update see https://github.com/JuliaLang/julia/issues/35911
3-
const Option{T} = Union{Nothing, Identity{T}}
3+
const Option{T} = Union{Const{Nothing}, Identity{T}}
44

5-
Option{T}(a::Nothing) where T = nothing
5+
Option{T}(::Const{Nothing}) where T = Const(nothing)
6+
Option{T}(::Nothing) where T = Const(nothing)
67
Option{T}(a::T) where T = Identity{T}(a)
7-
Option(a::Nothing) = nothing
8+
Option(::Const{Nothing}) = Const(nothing)
9+
Option(::Nothing) = Const(nothing)
810
Option(a::T) where T = Identity{T}(a)
9-
Option{T}() where T = nothing
10-
Option() = nothing
11+
Option{T}() where T = Const(nothing)
12+
Option() = Const(nothing)
1113

1214

1315
function iftrue(func::Function, b::Bool)
14-
b ? Identity(func()) : nothing
16+
b ? Identity(func()) : Const(nothing)
1517
end
1618
function iftrue(b::Bool, t)
17-
b ? Identity(t) : nothing
19+
b ? Identity(t) : Const(nothing)
1820
end
1921
function iffalse(func::Function, b::Bool)
20-
!b ? Identity(func()) : nothing
22+
!b ? Identity(func()) : Const(nothing)
2123
end
2224
function iffalse(b::Bool, t)
23-
!b ? Identity(t) : nothing
25+
!b ? Identity(t) : Const(nothing)
2426
end
2527

26-
issomething(m::Nothing) = false
27-
issomething(m::Identity) = true
28+
isoption(::Const{Nothing}) = true
29+
isoption(::Identity) = true
30+
isoption(other) = false
31+
2832

2933
Base.eltype(::Type{Option{T}}) where {T} = T
3034
Base.eltype(::Type{Option}) = Any

src/OptionEither.jl

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/convert.jl

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,29 @@ Base.convert(::Type{<:Vector}, x::ContextManager) = [x(identity)]
1313
# Const
1414
# -----
1515

16-
Base.convert(::Type{<:Const}, x::Nothing) = Const(nothing)
1716
function Base.convert(::Type{Const}, x::Vector)
1817
@assert !isempty(x) "can only convert empty Vector to Nothing, got $(x)"
1918
Const([])
2019
end
2120

22-
# Nothing
23-
# -------
24-
25-
function Base.convert(::Type{Nothing}, x::Vector)
26-
@assert !isempty(x) "can only convert empty Vector to Nothing, got $(x)"
27-
nothing
28-
end
29-
3021
# Identity
3122
# --------
3223

33-
# Nothing and Const are just passed through when asked to convert to identity
34-
# this is intended special behaviour in order for Identity + Nothing/Const to work together as Option/Either
35-
Base.convert(::Type{Identity}, x::Union{Nothing, Const}) = x
24+
# Const are just passed through when asked to convert to identity
25+
# this is intended special behaviour in order for Identity + Const to work together as Option/Either
26+
Base.convert(::Type{Identity}, x::Const) = x
3627
# ContextManager is executed
37-
Base.convert(::Type{<:Identity}, x::ContextManager) = Identity(x(identity))
28+
Base.convert(::Type{<:Identity}, x::ContextManager) = Identity(run(x))
3829

3930

4031
# ContextManager
4132
# --------------
4233

4334
Base.convert(::Type{<:ContextManager}, x::Identity) = @ContextManager cont -> cont(x.value)
4435

45-
# Note that we do not support convert from Nothing/Const to ContextManager.
36+
# Note that we do not support convert from Const to ContextManager.
4637
# ContextManager is similar to Identity a Container which always contains a single element,
47-
# however, unlike Identity, we cannot simply pass-through Nothing/Const and preserve the empty container by this trick.
38+
# however, unlike Identity, we cannot simply pass-through Const and preserve the empty container by this trick.
4839
# To map over ContextManager, you NEED to create a new ContextManager, if you don't want to run the contextmanager
4940
# immediately. Hence, also flatmap needs to create another ContextManager, i.e. single element container.
5041

@@ -69,8 +60,8 @@ Base.convert(::Type{Option}, x::Option) = x
6960

7061
Base.convert(::Type{Option{T}}, x::Identity) where T = Identity(Base.convert(T, x))
7162
Base.convert(::Type{Option{T}}, x::Identity{T}) where T = x # nothing to convert
72-
Base.convert(::Type{Option{T}}, x::Nothing) where T = x # nothing to convert
73-
Base.convert(::Type{Option}, x::Nothing) = x # nothing to convert
63+
Base.convert(::Type{Option{T}}, x::Const{Nothing}) where T = x # nothing to convert
64+
Base.convert(::Type{Option}, x::Const{Nothing}) = x # nothing to convert
7465
Base.convert(::Type{Option}, x::Identity) = x # nothing to convert
7566

7667

@@ -86,21 +77,3 @@ Base.convert(::Type{Either{<:Any, R}}, x::Identity) where {R} = Identity(Base.co
8677
Base.convert(::Type{Either{<:Any, R}}, x::Identity{R}) where {R} = x # nothing to convert
8778
Base.convert(::Type{Either{L, <:Any}}, x::Const) where {L} = Const(Base.convert(L, x.value))
8879
Base.convert(::Type{Either{L, <:Any}}, x::Const{L}) where {L} = x # nothing to convert
89-
90-
91-
# OptionEither
92-
# ------------
93-
94-
Base.convert(::Type{OptionEither{L, R}}, x::Identity) where {L, R} = Identity(Base.convert(R, x.value))
95-
Base.convert(::Type{OptionEither{L, R}}, x::Identity{R}) where {L, R} = x # nothing to convert
96-
Base.convert(::Type{OptionEither{L, R}}, x::Const) where {L, R} = Const(Base.convert(L, x.value))
97-
Base.convert(::Type{OptionEither{L, R}}, x::Const{L}) where {L, R} = x # nothing to convert
98-
99-
Base.convert(::Type{OptionEither{<:Any, R}}, x::Identity) where {R} = Identity(Base.convert(R, x.value))
100-
Base.convert(::Type{OptionEither{<:Any, R}}, x::Identity{R}) where {R} = x # nothing to convert
101-
Base.convert(::Type{OptionEither{L, <:Any}}, x::Const) where {L} = Const(Base.convert(L, x.value))
102-
Base.convert(::Type{OptionEither{L, <:Any}}, x::Const{L}) where {L} = x # nothing to convert
103-
104-
Base.convert(::Type{OptionEither{L, R}}, x::Nothing) where {L, R} = x # nothing to convert
105-
Base.convert(::Type{OptionEither}, x::Nothing) = x # nothing to convert
106-
Base.convert(::Type{OptionEither}, x::Identity) = x # nothing to convert

0 commit comments

Comments
 (0)