Public API
DataTypesBasic.Const
DataTypesBasic.ContextManager
DataTypesBasic.Either
DataTypesBasic.Identity
DataTypesBasic.Option
DataTypesBasic.Try
Base.isconst
DataTypesBasic.either
DataTypesBasic.getOption
DataTypesBasic.getleft
DataTypesBasic.getleftOption
DataTypesBasic.getright
DataTypesBasic.getrightOption
DataTypesBasic.iffalse
DataTypesBasic.iftrue
DataTypesBasic.iseither
DataTypesBasic.isfailure
DataTypesBasic.isidentity
DataTypesBasic.isleft
DataTypesBasic.isnone
DataTypesBasic.isoption
DataTypesBasic.isright
DataTypesBasic.issome
DataTypesBasic.issuccess
DataTypesBasic.istry
DataTypesBasic.@ContextManager
DataTypesBasic.@Try
DataTypesBasic.@TryCatch
DataTypesBasic.@either
Identity
DataTypesBasic.Identity
— TypeIdentity(:anything)
Identity is a simple wrapper, which works as a single-element container.
It can be used as the trivial Monad, and as such can be helpful in monadic abstractions. For those who don't know about Monads, just think of it like container-abstractions.
DataTypesBasic.isidentity
— Functionisidentity(Identity(3)) -> true
isidentity("anythingelse") -> false
returns true only if given an instance of Identity
Const
DataTypesBasic.Const
— TypeConst("anything")
DataType which behaves constant among map
, foreach
and the like. Just like an empty container, however with additional information about which kind of empty.
Base.isconst
— Methodisconst(Const(3)) -> true
isconst("anythingelse") -> false
returns true only if given an instance of DataTypesBasic.Const
Option
DataTypesBasic.Option
— TypeOption{T} = Union{Const{Nothing}, Identity{T}}
Option(nothing) == Const(nothing)
Option("anything but nothing") == Identity("anything but nothing")
Option() == Const(nothing)
Like Union{T, Nothing}
, however with container semantics. While Union{T, Nothing}
can be thought of like a value which either exists or not, Option{T} = Union{Identity{T}, Const{Nothing}}
is a container which is either empty or has exactly one element.
We reuse Identity
as representing the single-element-container and Const(nothing)
as the empty container.
DataTypesBasic.isoption
— Functionisoption(::Const{Nothing}) = true
isoption(::Identity) = true
isoption(other) = false
check whether something is an Option
DataTypesBasic.issome
— Functionissome(::Identity) = true
issome(::Const{Nothing}) = false
Similar to isright
, but only defined for Const{Nothing}
. Will throw MethodError when applied on other Const
.
DataTypesBasic.isnone
— Functionisnone(::Identity) = false
isnone(::Const{Nothing}) = true
Similar to isleft
, but only defined for Const{Nothing}
. Will throw MethodError when applied on other Const
.
DataTypesBasic.iftrue
— Functioniftrue(bool_condition, value)
iftrue(func, bool_condition)
iftrue(bool_condition) do
# only executed if bool_condition is true
end
Helper to create an Option based on some condition. If bool_condition
is true, the function func
is called with no arguments, and its result wrapped into Identity
. If bool_condition
is false, Option()
is returned.
DataTypesBasic.iffalse
— Functioniffalse(bool_condition, value)
iffalse(func, bool_condition)
iffalse(bool_condition) do
# only executed if bool_condition is true
end
Helper to create an Option based on some condition. If bool_condition
is false, the function func
is called with no arguments, and its result wrapped into Identity
. If bool_condition
is true, Option()
is returned.
Precisely the opposite of iftrue
.
DataTypesBasic.getOption
— FunctiongetOption(Identity(23)) == Option(23)
getOption(Const(:something)) == Option()
Convert to option, assuming you want to have the right value be preserved, and the left value represented as Option()
.
Either
DataTypesBasic.Either
— TypeEither{L, R} = Union{Const{L}, Identity{R}}
Either{Int, Bool}(true) == Identity(true)
Either{Int, Bool}(1) == Const(1)
Either{String}("left") == Const("left")
Either{String}(:anythingelse) == Identity(:anythingelse)
A very common type to represent Result or Failure. We reuse Identity
as representing "Success" and Const
for "Failure".
DataTypesBasic.iseither
— Functioniseither(::Const) = true
iseither(::Identity) = true
iseither(other) = false
check whether something is an Either
DataTypesBasic.isleft
— Functionisleft(::Const) = true
isleft(::Identity) = false
Identical to isconst
, but might be easier to read when working with Either
.
DataTypesBasic.isright
— Functionisright(::Const) = false
isright(::Identity) = true
Identical to isidentity
, but might be easier to read when working with Either
.
DataTypesBasic.either
— Functioneither(:left, bool_condition, "right")
If bool_condition
is true, it returns the right value, wrapped into Identity. Else returns left side, wrapped into Const.
Example
either(:left, 1 < 2, "right") == Identity("right")
DataTypesBasic.@either
— Macro@either true ? "right" : Symbol("left")
@either if false
"right"
else
:left
end
Simple macro to reuse ? operator and simple if-else for constructing Either.
DataTypesBasic.getleft
— Functiongetleft(Const(:something)) == :something
getleft(Identity(23)) # throws MethodError
Extract a value from a "left" Const
value. Will result in loud error when used on anything else.
DataTypesBasic.getright
— Functiongetright(Identity(23)) == 23
getright(Const(:something)) # throws MethodError
Extract a value from a "right" Identity
value. Will result in loud error when used on anything else. Identical to Base.get
but explicit about the site (and not defined for other things)
DataTypesBasic.getleftOption
— FunctiongetleftOption(Identity(23)) == Option()
getleftOption(Const(:something)) == Option(:something)
Convert to option, assuming you want to have the left value be preserved.
DataTypesBasic.getrightOption
— FunctiongetrightOption(Identity(23)) == Option(23)
getrightOption(Const(:something)) == Option()
Convert to option, assuming you want to have the right value be preserved. Identical to getOption
, just explicit about the site.
Try
DataTypesBasic.Try
— TypeTry{T} = Union{Const{<:Exception}, Identity{T}}
@Try(error("something happend")) isa Const(<:Thrown{ErrorException})
@Try(:successfull) == Identity(:successfull)
A specific case of Either
, where the Failure is always an Exception. This can be used as an alternative to using try-catch syntax and allows for very flexible error handling, as the error is now captured in a proper defined type. Often it is really handy to treat errors like other values (without the need of extra try-catch syntax which only applies to exceptions).
We reuse Identity
for representing the single-element-container and Const(<:Exception)
as the Exception thrown.
DataTypesBasic.@Try
— Macro@Try begin
your_code
end
Macro which directly captures an Excpetion into a proper Try
representation.
It translates to
try
r = your_code
Identity(r)
catch exc
Const(Thrown(exc, Base.catch_stack()))
end
DataTypesBasic.@TryCatch
— Macro@TryCatch YourException begin
your_code
end
A version of @Try
which catches only specific errors. Every other orrer will be rethrown
.
It translates to
try
r = your_code
Identity(r)
catch exc
if exc isa YourException
Const(Thrown(exc, Base.catch_stack()))
else
rethrow()
end
end
DataTypesBasic.istry
— Functionisoption(::Const{Nothing}) = true
isoption(::Identity) = true
isoption(other) = false
check whether something is a Try
DataTypesBasic.issuccess
— Functionissuccess(::Identity) = true
issuccess(::Const{<:Exception}) = false
Similar to isright
, but only defined for Const{<:Exception}
. Will throw MethodError when applied on other Const
.
DataTypesBasic.isfailure
— Functionisfailure(::Identity) = false
isfailure(::Const{<:Exception}) = true
Similar to isleft
, but only defined for Const{<:Exception}
. Will throw MethodError when applied on other Const
.
ContextManager
DataTypesBasic.ContextManager
— TypeContextManager(func)
As ContextManager we denote a computation which has a pre-computation and possibly a cleaning up step.
The single argument is supposed to be a function which expects one argument, the continuation function. Think of it like the following:
function contextmanagerready(cont)
# ... do something before
value = ... # create some value to work on later
result = cont(value) # pass the value to the continuation function (think like `yield`)
# ... do something before exiting, e.g. cleaning up
result # IMPORTANT: always return the result of the `cont` function
end
Now you can wrap it into ContextManager(contextmanagerready)
and you can use all the context manager functionalities right away.
There is a simple @ContextManager
for writing less parentheses
mycontextmanager(value) = @ContextManager function(cont)
println("got value = $value")
result = cont(value)
println("finished value = $value")
result
end
You can run it in two ways, either by just passing Base.identity
as the continuation function
julia> mycontextmanager(4)(x -> x)
got value = 4
finished value = 4
or for convenience we also overload Base.run
# without any extra arguments runs the contextmanager with Base.identity
run(mycontextmanager(4))
# also works with a given continuation, which makes for a nice do-syntax
run(x -> x, mycontextmanager(4))
run(mycontextmanager(4)) do x
x
end
DataTypesBasic.@ContextManager
— Macro@ContextManager function(cont); ...; end
There is a simple @ContextManager
for writing less parentheses
mycontextmanager(value) = @ContextManager function(cont)
println("got value = $value")
result = cont(value)
println("finished value = $value")
result
end