Skip to content

Commit

Permalink
Move Result to TryExperimental (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkf authored Mar 21, 2022
1 parent 0c3e52b commit ab235a1
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 50 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ can return `InvalidCharError()` or `EndOfBufferError()` as an error value:
```julia
using Try, TryExperimental

const Result{T,E} = Union{Ok{<:T},Err{<:E}}
# using TryExperimental: Result # (almost equivalent)

struct InvalidCharError <: Exception end
struct EndOfBufferError <: Exception end

Expand Down
4 changes: 4 additions & 0 deletions docs/src/experimental.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Experimental

```@docs
TryExperimental.Result
```

## [Customizing short-circuit evaluation](@id customize-short-circuit)

```@docs
Expand Down
1 change: 0 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

```@docs
Try
Result
Ok
Err
```
Expand Down
7 changes: 5 additions & 2 deletions lib/TryExperimental/src/TryExperimental.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ abstract type EmptyError <: Exception end
abstract type ClosedError <: Exception end
# abstract type FullError <: Exception end

const ConcreteResult = Try.Internal.ConcreteResult

macro and_then end
macro or_else end

Expand All @@ -54,6 +52,7 @@ module Internal
import ..TryExperimental: @and_then, @or_else
using ..TryExperimental: TryExperimental, Causes
using Try
using Try.Internal: AbstractResult

for n in names(TryExperimental; all = true)
startswith(string(n), "try") || continue
Expand All @@ -64,12 +63,16 @@ end
using Base.Meta: isexpr
using Base: IteratorEltype, HasEltype, IteratorSize, HasLength, HasShape

include("concrete.jl")
include("sugars.jl")
include("causes.jl")
include("base.jl")

end # module Internal

const Result = Internal.Result
const ConcreteResult = Internal.ConcreteResult

# TODO: move this to Maybe.jl
baremodule Maybe
function ok end
Expand Down
42 changes: 42 additions & 0 deletions lib/TryExperimental/src/concrete.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const DynamicResult{T,E} = Union{Ok{T},Err{E}}

function _ConcreteResult end

struct ConcreteResult{T,E} <: AbstractResult{T,E}
value::DynamicResult{T,E}

global _ConcreteResult(::Type{T}, ::Type{E}, value) where {T,E} = new{T,E}(value)
end

# Is this mixture of invariance and covariance good?
const Result{T,E} = Union{ConcreteResult{T,E},DynamicResult{<:T,<:E}}

Try.unwrap(result::ConcreteResult) = Try.unwrap(result.value)
Try.unwrap_err(result::ConcreteResult) = Try.unwrap_err(result.value)
Try.isok(result::ConcreteResult) = result.value isa Ok
Try.iserr(result::ConcreteResult) = result.value isa Err

_concrete(result::Ok) = _ConcreteResult(Try.oktype(result), Union{}, result)
_concrete(result::Err) = _ConcreteResult(Union{}, Try.errtype(result), result)

Base.convert(::Type{ConcreteResult{T,E}}, result::Ok) where {T,E} =
_ConcreteResult(T, E, convert(Ok{T}, result))
Base.convert(::Type{ConcreteResult{T}}, result::Ok) where {T} =
_ConcreteResult(T, Union{}, convert(Ok{T}, result))

Base.convert(::Type{ConcreteResult{T,E}}, result::Err) where {T,E} =
_ConcreteResult(T, E, convert(Err{E}, result))
Base.convert(::Type{ConcreteResult{<:Any,E}}, result::Err) where {E} =
_ConcreteResult(Union{}, E, convert(Err{E}, result))

function Base.convert(
::Type{ConcreteResult{T,E}},
result::ConcreteResult{T′,E′},
) where {T,E,T′<:T,E′<:E}
value = result.value
if value isa Ok
return _ConcreteResult(T, E, Ok{T}(value.value))
else
return _ConcreteResult(T, E, Err{E}(value.value))
end
end
File renamed without changes.
5 changes: 1 addition & 4 deletions src/Try.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
baremodule Try

export @?, Ok, Err, Result
export @?, Ok, Err

module InternalPrelude
abstract type AbstractResult{T,E} end
Expand Down Expand Up @@ -54,7 +54,6 @@ using ..Try.InternalPrelude: AbstractResult, _IsOkError
include("ExternalDocstrings.jl")
using .ExternalDocstrings: @define_docstrings

include("concrete.jl")
include("core.jl")
include("show.jl")
include("errortrace.jl")
Expand All @@ -64,8 +63,6 @@ include("branch.jl")

end # module Internal

const Result = Internal.Result

Internal.@define_docstrings

end # baremodule Try
11 changes: 0 additions & 11 deletions src/concrete.jl

This file was deleted.

30 changes: 0 additions & 30 deletions src/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ Try.Ok(::Type{T}) where {T} = Try.Ok{Type{T}}(T)
Try.Err(value) = Try.Err(value, maybe_backtrace())
Try.Err{E}(value) where {E<:Exception} = Try.Err{E}(value, maybe_backtrace())

Try.unwrap(result::ConcreteResult) = Try.unwrap(result.value)
Try.unwrap(ok::Ok) = ok.value
Try.unwrap(err::Err) = _throw(err)

Try.unwrap_err(result::ConcreteResult) = Try.unwrap_err(result.value)
Try.unwrap_err(ok::Ok) = throw(Try.IsOkError(ok))
Try.unwrap_err(err::Err) = err.value

_throw(err::ConcreteResult) = _throw(err.value)
function _throw(err::Err)
if err.backtrace === nothing
throw(err.value)
Expand All @@ -34,31 +31,6 @@ Base.convert(::Type{Err{E}}, err::Err) where {E} = Err{E}(err.value)
# chain-of-custody Julep. Maybe this should be done only when the destination
# type is `AbstractResult{<:Any,E′}` s.t. `!(err.value isa E′)`.

_concrete(result::Ok) = _ConcreteResult(Try.oktype(result), Union{}, result)
_concrete(result::Err) = _ConcreteResult(Union{}, Try.errtype(result), result)

Base.convert(::Type{ConcreteResult{T,E}}, result::Ok) where {T,E} =
_ConcreteResult(T, E, convert(Ok{T}, result))
Base.convert(::Type{ConcreteResult{T}}, result::Ok) where {T} =
_ConcreteResult(T, Union{}, convert(Ok{T}, result))

Base.convert(::Type{ConcreteResult{T,E}}, result::Err) where {T,E} =
_ConcreteResult(T, E, convert(Err{E}, result))
Base.convert(::Type{ConcreteResult{<:Any,E}}, result::Err) where {E} =
_ConcreteResult(Union{}, E, convert(Err{E}, result))

function Base.convert(
::Type{ConcreteResult{T,E}},
result::ConcreteResult{T′,E′},
) where {T,E,T′<:T,E′<:E}
value = result.value
if value isa Ok
return _ConcreteResult(T, E, Ok{T}(value.value))
else
return _ConcreteResult(T, E, Err{E}(value.value))
end
end

Try.oktype(::Type{R}) where {T,R<:AbstractResult{T}} = T
Try.oktype(result::AbstractResult) = Try.oktype(typeof(result))

Expand All @@ -67,8 +39,6 @@ Try.errtype(result::AbstractResult) = Try.errtype(typeof(result))

Try.isok(::Ok) = true
Try.isok(::Err) = false
Try.isok(result::ConcreteResult) = result.value isa Ok

Try.iserr(::Ok) = false
Try.iserr(::Err) = true
Try.iserr(result::ConcreteResult) = result.value isa Err
3 changes: 2 additions & 1 deletion src/docs/Err.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Err{E} <: Result{T,E}
Err(value::E) -> err::Err{E}
Err{E}(value) -> err::Err{E}
3 changes: 2 additions & 1 deletion src/docs/Ok.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Ok{T} <: Result{T,E}
Ok(value::T) -> ok::Ok{T}
Ok{T}(value) -> ok::Ok{T}

0 comments on commit ab235a1

Please sign in to comment.