Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with types #22

Open
lehoff opened this issue Sep 21, 2024 · 5 comments
Open

Problem with types #22

lehoff opened this issue Sep 21, 2024 · 5 comments
Labels
documentation Improvements or additions to documentation

Comments

@lehoff
Copy link

lehoff commented Sep 21, 2024

I have define the following:

module TVJulia

@data MinuteOutcome begin
    HomeGoal
    AwayGoal
    NoGoal
    BothGoal
end

@data Score begin
    ZeroZero
    ZeroOne
    OneZero
    OneOne
    Even
    Plus(Int)
    Minus(Int)
end

# const SCORES::Vector{Score.Type} = [
#     Score.ZeroZero, Score.ZeroOne, Score.OneZero, Score.OneOne, Score.Even,
#     Score.Plus(1), Score.Plus(2), Score.Plus(3), Score.Plus(4), Score.Plus(5),
#     Score.Minus(1), Score.Minus(2), Score.Minus(3), Score.Minus(4), Score.Minus(5)]
function scores() 
    Score.Type[
        Score.ZeroZero::Score.Type, Score.ZeroOne, Score.OneZero, Score.OneOne, Score.Even,
        Score.Plus(1), Score.Plus(2), Score.Plus(3), Score.Plus(4), Score.Plus(5),
        Score.Minus(1), Score.Minus(2), Score.Minus(3), Score.Minus(4), Score.Minus(5)
    ]
end

function Base.:+(s::Score.Type, mo::MinuteOutcome.Type)
    @match mo begin
        MinuteOutcome.HomeGoal => 
            @match s begin
                Score.ZeroZero => Score.OneZero
                Score.ZeroOne  => Score.OneOne
                Score.OneZero  => Score.Plus(2)
                Score.OneOne   => Score.Plus(1)
                Score.Even     => Score.Plus(1)
                Score.Plus(n)  => Score.Plus(min(n+1, 5))
                Score.Minus(1) => Score.Even
                Score.Minus(n) => Score.Minus(n-1)
            end
        MinuteOutcome.AwayGoal =>
            @match s begin
                Score.ZeroZero => Score.ZeroOne
                Score.ZeroOne  => Score.Minus(2)
                Score.OneZero  => Score.OneOne
                Score.OneOne   => Score.Minus(1)
                Score.Even     => Score.Minus(1)
                Score.Plus(1)  => Score.Even
                Score.Plus(n)  => Score.Plus(n-1)
                Score.Minus(n) => Score.Minus(min(n+1, 5))                
            end
        MinuteOutcome.BothGoal =>
            @match s begin
                Score.ZeroZero => Score.OneOne
                Score.ZeroOne  => Score.Minus(1)
                Score.OneZero  => Score.Plus(1)
                Score.OneOne   => Score.Even
                _ => s
            end
        MinuteOutcome.NoGoal => s
    end
end

But I am running into problems - one after the other.

> TVJulia.scores()
MethodError: Cannot `convert` an object of type Type{Main.TVJulia.Score.ZeroZero} to an object of type Main.TVJulia.Score.Type

Closest candidates are:
  convert(::Type{T}, ::T) where T
   @ Base Base.jl:84
  Main.TVJulia.Score.Type(::Any)
   @ Main.TVJulia none:0


Stacktrace:
 [1] setindex!(A::Vector{Main.TVJulia.Score.Type}, x::Type, i1::Int64)
   @ Base ./array.jl:1021
 [2] (::Base.var"#114#115"{Vector{Main.TVJulia.Score.Type}})(i::Int64, v::Type)
   @ Base ./array.jl:456
 [3] afoldl(::Base.var"#114#115"{Vector{Main.TVJulia.Score.Type}}, ::Int64, ::Type, ::Type, ::Type, ::Type, ::Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type, ::Main.TVJulia.Score.Type)
   @ Base ./operators.jl:544
 [4] getindex(::Type{Main.TVJulia.Score.Type}, ::Type, ::Type, ::Type, ::Vararg{Any})
   @ Base ./array.jl:455
 [5] scores()
   @ Main.TVJulia ~/git/lehoff/TVJulia/src/TVJulia.jl:97
 [6] top-level scope
   @ In[97]:1

When I try to use my + operator I get:

> TVJulia.Score.ZeroZero + TVJulia.MinuteOutcome.HomeGoal

MethodError: no method matching +(::Type{Main.TVJulia.Score.ZeroZero}, ::Type{Main.TVJulia.MinuteOutcome.HomeGoal})

Closest candidates are:
  +(::Any, ::Any, ::Any, ::Any...)
   @ Base operators.jl:587


Stacktrace:
 [1] top-level scope
   @ In[88]:1

This leaves me rather confused.

Happy to conduct further investigations if that would be of any help.

@Roger-luo
Copy link
Owner

Unfortunately we can't have real singleton (e.g type is the same as instance) this is not supported by Julia, so you need to explicitly write the instance (otherwise that's just a variant type). I was actually thinking this, maybe we should just remove the singleton syntax.

@lehoff
Copy link
Author

lehoff commented Sep 22, 2024

Not sure I understand what I need to do - could you give an example?

Follow up question: what would happen if I used ZeroZero() instead of ZeroZero? Can I still compare them for equality?

@Roger-luo
Copy link
Owner

You only need to use ZeroZero() in the pattern match (whenever you need to construct an instance), e.g

julia> Score.ZeroZero
Main.Score.ZeroZero

julia> Score.ZeroZero()
Main.Score.var"typeof(Score)"(Main.Score.var"##Storage#ZeroZero"())

this is what I meant there is no real singleton type, it was only a syntax sugar, ZeroZero() is the actual instance.

@Roger-luo Roger-luo added the documentation Improvements or additions to documentation label Sep 23, 2024
@Roger-luo
Copy link
Owner

Roger-luo commented Sep 23, 2024

actually maybe I'll just correct your script here

module TVJulia

@data MinuteOutcome begin
    HomeGoal
    AwayGoal
    NoGoal
    BothGoal
end

@data Score begin
    ZeroZero
    ZeroOne
    OneZero
    OneOne
    Even
    Plus(Int)
    Minus(Int)
end

# const SCORES::Vector{Score.Type} = [
#     Score.ZeroZero, Score.ZeroOne, Score.OneZero, Score.OneOne, Score.Even,
#     Score.Plus(1), Score.Plus(2), Score.Plus(3), Score.Plus(4), Score.Plus(5),
#     Score.Minus(1), Score.Minus(2), Score.Minus(3), Score.Minus(4), Score.Minus(5)]
function scores() 
    Score.Type[
        Score.ZeroZero(), Score.ZeroOne(), Score.OneZero(), Score.OneOne(), Score.Even(),
        Score.Plus(1), Score.Plus(2), Score.Plus(3), Score.Plus(4), Score.Plus(5),
        Score.Minus(1), Score.Minus(2), Score.Minus(3), Score.Minus(4), Score.Minus(5)
    ]
end

function Base.:+(s::Score.Type, mo::MinuteOutcome.Type)
    @match mo begin
        MinuteOutcome.HomeGoal => 
            @match s begin
                Score.ZeroZero() => Score.OneZero()
                Score.ZeroOne()  => Score.OneOne()
                Score.OneZero()  => Score.Plus(2)
                Score.OneOne()   => Score.Plus(1)
                Score.Even()     => Score.Plus(1)
                Score.Plus(n)  => Score.Plus(min(n+1, 5))
                Score.Minus(1) => Score.Even()
                Score.Minus(n) => Score.Minus(n-1)
            end
        MinuteOutcome.AwayGoal =>
            @match s begin
                Score.ZeroZero() => Score.ZeroOne()
                Score.ZeroOne()  => Score.Minus(2)
                Score.OneZero()  => Score.OneOne
                Score.OneOne()   => Score.Minus(1)
                Score.Even()     => Score.Minus(1)
                Score.Plus(1)  => Score.Even()
                Score.Plus(n)  => Score.Plus(n-1)
                Score.Minus(n) => Score.Minus(min(n+1, 5))                
            end
        MinuteOutcome.BothGoal =>
            @match s begin
                Score.ZeroZero() => Score.OneOne()
                Score.ZeroOne()  => Score.Minus(1)
                Score.OneZero()  => Score.Plus(1)
                Score.OneOne()   => Score.Even()
                _ => s
            end
        MinuteOutcome.NoGoal() => s
    end
end

@jakobjpeters
Copy link

maybe we should just remove the singleton syntax.

That would feel more consistent 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants