I have a type which contains two slots, and it is important that the
types of them satisfy certain constraints. I can enforce that in the
constructor: see first and second implementations below. However, if I
want to compute types directly in the definition (see third
implementation), I end up with a TypeVar object I don't know how to deal
with (even though I read the "More about types" section in the manual,
sorry). Is this even possible?

[Note: I also asked on Gitter, but did not get a solution, or an
explanation.]

# first implementation: dd1 maps values to types
# uses constructor to constrain, works

dd1(::Int) = Float64             # for the sake of example

immutable Foo1{T,S}
    a::T
    b::Set{S}
    function Foo1{T,S}(a::T, b::Set{S})
        @assert S ≡ dd1(a)
        new(a, b)
    end
end

Foo1{T,S}(a::T, b::Set{S}) = Foo1{T,S}(a,b)

Foo1(1, Set([9.0]))             # OK
foo1(1, Set(9))                 # error

# second implementation: dd2 maps types to types
# uses constructor to constrain, works

dd2(::Type{Int}) = Float64

immutable Foo2{T,S}
    a::T
    b::Set{S}
    function Foo2{T,S}(a::T, b::Set{S})
        @assert S ≡ dd2(T)
        new(a, b)
    end
end

Foo2{T,S}(a::T, b::Set{S}) = Foo2{T,S}(a,b)

Foo2(1, Set([9.0]))             # OK
Foo2(1, Set(9))                 # error

# third implementation, types to types

immutable Foo3{T,S}
    a::T
    b::Set{dd2(T)}
end
## ERROR: MethodError: no method matching dd2(::TypeVar)

Reply via email to