I'm trying to create a generic function to apply some image filters.

The applyFilters(_:) function uses Parameter Pack of ImageFilter.

Calling applyFilters(_:) with static functions that take a type literal I got the error:

Cannot convert value of type #ExpressibleType to expected argument type #Type.

But creating an object directly from ImageBlurFilter.Radius or ImageExposureAdjust.Scalar work fine.

protocol ImageFilter {
    
    associatedtype Processor: ImageFilterProcessor
    /**/
}

protocol ImageFilterProcessor { /**/ }

struct ImageBlurFilter: ImageFilter {
        
    init(radius: Radius) { /**/ }
    
    struct Processor: ImageFilterProcessor { /**/ }
    
    struct Radius: ExpressibleByIntegerLiteral {
        
        init(integerLiteral value: Int) { /**/ }
    }
}

struct ImageExposureAdjust: ImageFilter {
    
    init(scalar: Scalar) { /**/ }
    
    struct Processor: ImageFilterProcessor { /**/ }
    
    struct Scalar: ExpressibleByFloatLiteral {
        
        init(floatLiteral value: Double) { /**/ }
    }
}

extension ImageFilter where Self == ImageBlurFilter {
    
    static func blur(radius: ImageBlurFilter.Radius) -> ImageBlurFilter {
        ImageBlurFilter(radius: radius)
    }
}

extension ImageFilter where Self == ImageExposureAdjust {
    
    static func exposureAdjust(scalar: ImageExposureAdjust.Scalar) -> ImageExposureAdjust {
        ImageExposureAdjust(scalar: scalar)
    }
}

func applyFilters<each Filter: ImageFilter>(_ filter: repeat each Filter) {
    let _ = (repeat (each filter))
}

func test() {
    applyFilters(
        .blur(radius: 10), // ❌ Cannot convert value of type 'Int' to expected argument type 'ImageBlurFilter.Radius'
        .exposureAdjust(scalar: 0.5) // ❌ Cannot convert value of type 'Double' to expected argument type 'ImageExposureAdjust.Scalar'
    )
    
    applyFilters(
        .blur(radius: ImageBlurFilter.Radius(10)), // ✅
        .exposureAdjust(scalar: ImageExposureAdjust.Scalar(0.5)) // ✅
    )
    
    let blurRadius: ImageBlurFilter.Radius = 10 
    let exposureAdjustScalar: ImageExposureAdjust.Scalar = 0.5
    
    applyFilters(
        .blur(radius: blurRadius), // ✅
        .exposureAdjust(scalar: exposureAdjustScalar) // ✅
    )
}
0

There are 0 best solutions below