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?