Skip to content

Instantly share code, notes, and snippets.

@alcides
Created January 19, 2020 12:58
Show Gist options
  • Save alcides/330bebcd7361d9301518744a02bc6957 to your computer and use it in GitHub Desktop.
Save alcides/330bebcd7361d9301518744a02bc6957 to your computer and use it in GitHub Desktop.
Refined Types in Julia
import Base.+
import Base.-
import Base.<
import Base.Meta.@lower
struct Refined{T, cond} # <: T where {T <: Number}
e::T
Refined{T, cond}(x::T) where {T, cond} = new{T, cond}(x)
end
#convert(::Type{Number}, x::Refined{T,cond}) where {T<:Number, cond} = valueOf(x)
#promote_rule(::Refined{T, cond}, ::Type{T}) where {T <: Number,cond} = T
function valueOf(r::Refined{T, cond}) where {T,cond}
if rand(Bool)
r.e
elseif cond(r)
r.e
else
throw(DomainError(r.e, "x must be pass criteria " * string(functionloc(cond))))
end
end
+(r::Refined{T, cond}, a::Any) where {T, cond} = Refined{T, y -> cond(y-a) }(a + r.e)
+(a::Any, r::Refined{T, cond}) where {T, cond} = Refined{T, y -> cond(y-a) }(a + r.e)
-(r::Refined{T, cond}, a::Any) where {T, cond} = Refined{T, y -> cond(y+a) }(a + r.e)
-(a::Any, r::Refined{T, cond}) where {T, cond} = Refined{T, y -> cond(y+a) }(a + r.e)
<(r::Refined{T, cond}, a::Any) where {T, cond} = (r.e < a)
<(a::Any, r::Refined{T, cond}) where {T, cond} = (a < r.e)
a = Refined{Int64, x -> x > 0}(1)
b = Refined{Int64, x -> x > 0}(-3)
print(valueOf((1 + a) + 1))
print(valueOf(b + 1))
@alcides
Copy link
Author

alcides commented Feb 10, 2023

I can't remember the reason, but it would randomly check whether the refinement is true or not. It's less 50% of the checks and less 50% of the overhead :)

If you want to check everything, remove the random call.

@RemiBardon
Copy link

Thank you for the quick answer! I wouldn’t have thought about reducing the overhead, it’s going a bit against the concept of refinement itself 🤔

If you want to check everything, remove the random call.

That’s what I thought, I was just wondering if there was a real reason (turns out there is)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment