As an example of what I mean, suppose that I'm trying to make a currency 
type for various currencies:

abstract cash

type usd <: cash
  a::Int64
  b::Int64
  function usd(a,b)
    b>=100 && error("Too much of smaller currency unit (over 99).")
    (b<0 || a<0) && error("Cannot have negative amounts.")
    new(a,b)
  end
end
type gbp <: cash
  a::Int64
  b::Int64
  function gbp(a,b)
    b>=100 && error("Too much of smaller currency unit (over 99).")
    (b<0 || a<0) && error("Cannot have negative amounts.")
    new(a,b)
  end
end

function Base.(:+){T<:cash}(x::T, y::T)
  total = 100x.a+100y.a+x.b+y.b
  return T(div(total, 100), total%100)
end

I'm able to define addition once for any subtype of cash. On the other 
hand, I have to write out a large amount of almost identical code each time 
I want to define a new subtype of cash. Is there some way I can define this 
once in an abstract manner (with any manually specified constructor 
overriding the general one), so that we could have something like:

abstract cash
general type T <: cash
  a::Int64
  b::Int64
  function T(a::Int64,b::Int64)
    b>=100 && error("Too much of smaller currency unit (over 99).")
    (b<0 || a<0) && error("Cannot have negative amounts.")
    new(a,b)
  end
end

type usd <: cash end
type gbp <: cash end
type whole <: cash
  function whole(a,b)
    a<0 && error("Cannot have negative amounts.")
    b != 0 && error("Must be whole amount.")
    new(a,b)
  end
end


Reply via email to