How about

immutable MyType{T<:Real}
    x::T
    v::Vector{T}
    s::String

    function MyType(x, v, s)
        x = subtractpi(x)
        v = map(subtractpi, v)
        new(x, v, s)
    end
end
MyType{T1<:Real, T2<:Real}(x::T1, v::Vector{T2}, s::String) = 
(T=promote_type(T1,T2); MyType{T}(x, v, s))

T1 and T2 are both needed to fulfil 5.  Otherwise calling `MyType(11.4, [1, 2, 
55])
will set T to Float64 and thus error on the array

On Wed, 2014-11-26 at 22:20, Marc Gallant <[email protected]> wrote:
> Suppose I have a type called MyType that has one floating point field "x". 
> When constructed, if the value provided for "x" is greater than, let's say, 
> 5, it has pi subtracted from it. For example,
>
> a = MyType(4)  # x = 4.0
> b = MyType(-11) # x = 11.0
> c = MyType(10)  # x = 6.8584
> d = MyType(-1.443)  # x = -1.443
>
> What is the best way to declare MyType and its constructor(s) to ensure 
> that:
>
> 1. You can provide MyType with any real number to construct it
> 2. typeof(a.x) and typeof(c.x) are both Float64
> 3. The pi constraint is properly applied (is an inner constructor 
> appropriate here?)
> 4. The same behaviour applies to the entries of a second field "y" that is 
> a vector (e.g., MyType(10, [3, 10, 11, -2]) has x = 6.8584, y = [3.0, 
> 6.8584, 7.8584, -2.0]).
> 5. (if possible) You can construct MyType from a mixture of real number 
> types (e.g., MyType(11.4, [1, 2, 55]))
> 6. MyType has a third field "z" that is a string
>
> Here is an implementation I wrote that doesn't meet 1, 5, or 6:
>
> function subtractpi(x::Real)
>     x, y = promote(x, x - pi)
>     return x > 5 ? y : x
> end
>
> immutable MyType{T<:FloatingPoint}
>     x::T
>     v::Vector{T}
>
>     function MyType(x, v)
>         x = subtractpi(x)
>         v = map(subtractpi, v)
>         new(x, v)
>     end
> end
> MyType{T<:FloatingPoint}(x::T, v::Vector{T}) = MyType{T}(x, v)
>
> Thanks. I am working on my understanding of types in Julia.

Reply via email to