is it possible to create a new property type?

I can do this with a Float or a Double, but I'm curious...

can I define a new property type?


the general idea is to make a new Kind of float that is limited to values > 0 & < 1.

creating a normalized float.


I could build it as a structure:


struct normalizedFloat {
     var value: Float{
         get{return internalValue}

         set{
               internalValue = Float.minimum(Float.maximum(value, 0), 1)
          }
     }
     var internalValue : Float = 0
}

but that creates extra work any time a 'normalized float' comes up in the data...


var norm : normalizedFloat = normalizedFloat(value : 0.123)

instead of :

var norm : normalizedFloat = 0.124


I have some experience overloading operators, by no means am I an expert at that... but this seems 'next level' compared to that. what kinds of search terms should I use to find out more? is it even possible?

I will not discuss how this normalization is done, but you could use extension.


I tested this, either through a var or a mutating func:


extension Float {
    var normalized : Float {
        if self > 1 { return 1.0 }
        if self < 0 { return 0 }
        return self
    }

    mutating func normalize() {
        if self > 1 {
            self = 1.0
        } else if self < 0 {
            self = 0
        }
    }
}


var f : Float = 1.2

print(f.normalized) // creates a new var, f not modified

f.normalize() // f is modified

print(f)

Accepted Answer

In Swift, there's no simple way to define a subtype of some existing type with sort of additional constraints.


You can define your own float type:

struct NormalizedFloat {
    var value: Float{
        get{return internalValue}
        
        set{
            internalValue = Float.minimum(Float.maximum(newValue, 0), 1)
        }
    }
    private var internalValue : Float = 0
}


But you may need to define bunch of operators, methods or properties or something like those to use it similar to Float.

protocol FloatSubtype {
    var floatValue: Float {get}
    
    init(floatValue: Float)
}

extension NormalizedFloat: FloatSubtype {
    var floatValue: Float {
        return value
    }
    
    init(floatValue: Float) {
        self.value = floatValue
    }
}

extension FloatSubtype {
    static func + (lhs: Float, rhs: Self) -> Self {
        return Self(floatValue: lhs + rhs.floatValue)
    }
    static func + (lhs: Self, rhs: Float) -> Self {
        return Self(floatValue: lhs.floatValue + rhs)
    }
    static func + (lhs: Self, rhs: Self) -> Self {
        return Self(floatValue: lhs.floatValue + rhs.floatValue)
    }
    
    static func - (lhs: Float, rhs: Self) -> Self {
        return Self(floatValue: lhs - rhs.floatValue)
    }
    static func - (lhs: Self, rhs: Float) -> Self {
        return Self(floatValue: lhs.floatValue - rhs)
    }
    static func - (lhs: Self, rhs: Self) -> Self {
        return Self(floatValue: lhs.floatValue - rhs.floatValue)
    }
    
    static func * (lhs: Float, rhs: Self) -> Self {
        return Self(floatValue: lhs * rhs.floatValue)
    }
    static func * (lhs: Self, rhs: Float) -> Self {
        return Self(floatValue: lhs.floatValue * rhs)
    }
    static func * (lhs: Self, rhs: Self) -> Self {
        return Self(floatValue: lhs.floatValue * rhs.floatValue)
    }
    
    static func / (lhs: Float, rhs: Self) -> Self {
        return Self(floatValue: lhs / rhs.floatValue)
    }
    static func / (lhs: Self, rhs: Float) -> Self {
        return Self(floatValue: lhs.floatValue / rhs)
    }
    static func / (lhs: Self, rhs: Self) -> Self {
        return Self(floatValue: lhs.floatValue / rhs.floatValue)
    }
    
    //You may need many other operations or methods...
}

extension NormalizedFloat: ExpressibleByFloatLiteral, ExpressibleByIntegerLiteral {
    init(floatLiteral value: Float) {
        self.init(floatValue: value)
    }

    init(integerLiteral value: Int) {
        self.init(floatValue: Float(value))
    }
}
extension NormalizedFloat: CustomStringConvertible, CustomDebugStringConvertible {
    var description: String {
        return self.value.description
    }
    var debugDescription: String {
        return self.value.debugDescription
    }
}

With these setup, you can write something like this:

var norm1: NormalizedFloat = 0.124
var norm2: NormalizedFloat = 0.248
print(norm1 + norm2) //->0.37199998


There may be some ways to create a subtype more easily in the furture Swift. You should better visit swift.org.

so defining my own struct... that's what I did (before I decided I needed a refernce type, and converted everything to objects) and it was fine.

I can work with that.

You've answered my question, and the answer is sort of.

if I hadn't disembarked from Structs to Classes I's probably go ahead and duplicate what you've done. That would work for me, thanks!

is it possible to create a new property type?
 
 
Q