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.