Public API
DataTypesBasic.ConstDataTypesBasic.ContextManagerDataTypesBasic.EitherDataTypesBasic.IdentityDataTypesBasic.OptionDataTypesBasic.TryBase.isconstDataTypesBasic.eitherDataTypesBasic.getOptionDataTypesBasic.getleftDataTypesBasic.getleftOptionDataTypesBasic.getrightDataTypesBasic.getrightOptionDataTypesBasic.iffalseDataTypesBasic.iftrueDataTypesBasic.iseitherDataTypesBasic.isfailureDataTypesBasic.isidentityDataTypesBasic.isleftDataTypesBasic.isnoneDataTypesBasic.isoptionDataTypesBasic.isrightDataTypesBasic.issomeDataTypesBasic.issuccessDataTypesBasic.istryDataTypesBasic.@ContextManagerDataTypesBasic.@TryDataTypesBasic.@TryCatchDataTypesBasic.@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") -> falsereturns 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") -> falsereturns 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) = falsecheck whether something is an Option
DataTypesBasic.issome — Functionissome(::Identity) = true
issome(::Const{Nothing}) = falseSimilar to isright, but only defined for Const{Nothing}. Will throw MethodError when applied on other Const.
DataTypesBasic.isnone — Functionisnone(::Identity) = false
isnone(::Const{Nothing}) = trueSimilar 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
endHelper 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
endHelper 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) = falsecheck whether something is an Either
DataTypesBasic.isleft — Functionisleft(::Const) = true
isleft(::Identity) = falseIdentical to isconst, but might be easier to read when working with Either.
DataTypesBasic.isright — Functionisright(::Const) = false
isright(::Identity) = trueIdentical 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
endSimple macro to reuse ? operator and simple if-else for constructing Either.
DataTypesBasic.getleft — Functiongetleft(Const(:something)) == :something
getleft(Identity(23)) # throws MethodErrorExtract 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 MethodErrorExtract 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
endMacro which directly captures an Excpetion into a proper Tryrepresentation.
It translates to
try
r = your_code
Identity(r)
catch exc
Const(Thrown(exc, Base.catch_stack()))
endDataTypesBasic.@TryCatch — Macro@TryCatch YourException begin
your_code
endA 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
endDataTypesBasic.istry — Functionisoption(::Const{Nothing}) = true
isoption(::Identity) = true
isoption(other) = falsecheck whether something is a Try
DataTypesBasic.issuccess — Functionissuccess(::Identity) = true
issuccess(::Const{<:Exception}) = falseSimilar to isright, but only defined for Const{<:Exception}. Will throw MethodError when applied on other Const.
DataTypesBasic.isfailure — Functionisfailure(::Identity) = false
isfailure(::Const{<:Exception}) = trueSimilar 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
endNow 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
endYou 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 = 4or 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
endDataTypesBasic.@ContextManager — Macro@ContextManager function(cont); ...; endThere 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