Generic way to do math on protocol extensions

Viewed 428

Goal

I want to extend basic types like Int, Double, Float... with more flexible properties and make it presentable in a chart on my app. For example, I made a chart draw that is suitable only for displaying Intbut cannot really display Float. I want to make sure when I pass arguments to this view it will display correctly.

Solution

So I made a protocol (for this example made it like this):

protocol SimplyChartable { 
        static func max(_ dataSet: [SimplyChartable]) -> SimplyChartable
}

And then make an extension for some types:

extension Int: SimplyChartable { }
extension Double: SimplyChartable { } 
extension Float: SimplyChartable { } 

and so on ...

Problem

This will be all numeric types, and whenever I pass it as numeric types to a func I need to extend all extension like this:

public static func max(_ dataSet: [SimplyChartable]) -> SimplyChartable { 
    return (dataSet as? [Int])?.max() ?? 0
}

But for Double func will be identical.

So for min I will end up with similar function, the same for divide, adding , some other math... There is a way to write it once and reuse for every type that extends this protocol?

I found out that:

    let dataType = type(of: maxValue) /* where `maxValue` is SimplyChartable*/

Will return original type as rawValue. But output of a method type(of is a Metatype and I cannot return it from function and then add two values of this type. So for example this code will not work:

let val1 = SimplyChartable(4)
let val2 = SimplyChartable(2)
let sum = val1 + val2

And how to make it work not ending up with 3 functions like this:

let val1 = SimplyChartable(4)
let val2 = SimplyChartable(2)
let sum = (val1 as! Int) + (val2 as! Int)
4 Answers
Related