I am exploring the possibility to have a protocol that can be initialized with basic type literals if its associatedtype is expressible by the required type.
public protocol WrappedValueLiteralExpressible {
associatedtype WrappedValue
var value: WrappedValue { get }
init(value: WrappedValue)
}
For ExpressibleByBooleanLiteral, ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral, ExpressibleByUnicodeScalarLiteral, ExpressibleByExtendedGraphemeClusterLiteral, ExpressibleByStringLiteral, the following extensions work fine:
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByBooleanLiteral {
public init(booleanLiteral value: WrappedValue.BooleanLiteralType) {
self.init(value: WrappedValue(booleanLiteral: value))
}
}
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByIntegerLiteral {
public init(integerLiteral value: WrappedValue.IntegerLiteralType) {
self.init(value: WrappedValue(integerLiteral: value))
}
}
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByFloatLiteral {
public init(floatLiteral value: WrappedValue.FloatLiteralType) {
self.init(value: WrappedValue(floatLiteral: value))
}
}
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByUnicodeScalarLiteral {
public init(unicodeScalarLiteral value: WrappedValue.UnicodeScalarLiteralType) {
self.init(value: WrappedValue(unicodeScalarLiteral: value))
}
}
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByExtendedGraphemeClusterLiteral {
public init(extendedGraphemeClusterLiteral value: WrappedValue.ExtendedGraphemeClusterLiteralType) {
self.init(value: WrappedValue(extendedGraphemeClusterLiteral: value))
}
}
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByStringLiteral {
public init(stringLiteral value: WrappedValue.StringLiteralType) {
self.init(value: WrappedValue(stringLiteral: value))
}
}
However, for ExpressibleByArrayLiteral and ExpressibleByDictionaryLiteral, a compiling error
Non-nominal type 'Self.WrappedValue' does not support explicit initialization
will prompt with following extension:
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByArrayLiteral {
public init(arrayLiteral elements: WrappedValue.ArrayLiteralElement...) {
self.init(value: WrappedValue(arrayLiteral: elements))
}
}
extension WrappedValueLiteralExpressible where WrappedValue: ExpressibleByDictionaryLiteral {
public init(arrayLiteral elements: (WrappedValue.Key, WrappedValue.Value)...) {
self.init(value: WrappedValue(dictionaryLiteral: elements))
}
}
This is where I got confused. If WrappedValue conforms to ExpressibleByArrayLiteral, then the required initializer (init(arrayLiteral elements: Self.ArrayLiteralElement...)) must be sufficient to initialize an instance of type WrappedValue, and that instance is all it needs to initialize an instance of any type that conforms to protocol WrappedValueLiteralExpressible.
So why is there that error, and how does error get generated?