[swift-evolution] TreeLiteralConvertible

Brent Royal-Gordon brent at architechies.com
Thu Apr 14 16:20:24 CDT 2016


> No, you just need Tree to conform to both ArrayLiteralConvertible and IntegerLiteralConvertible, and it implements the latter by building a Value out of it.

That not only doesn't work if your type isn't a LiteralConvertible, it also doesn't work if you want to build a literal with variables:

	let myTree: Tree = [1, [2, three]]

The real missing feature here is implicit lifting like Optional offers. With a LiftingConvertible protocol, you could say something like this:

	enum Tree<Value> {
		case leaf(Value)
		case branches([Tree<Value>])
	}
	
	extension Tree: ArrayLiteralConvertible {
		init(arrayLiteral branches: Tree<Value>...) {
			self = .branches(branches)
		}
	}
	
	extension Tree: LiftingConvertible {
		init(lifting value: Value) {
			self = .leaf(value)
		}
	}

However, even without implicit lifting, you should still be able to write trees with just ArrayLiteralConvertible by explicitly lifting the leaves:

	let myTree: Tree = [.leaf(1), [.leaf(2), .leaf(three)]]

That isn't great, but it's not awful, either.

For that matter, you could write a semi-implicit lifting feature:

	protocol LiftingConvertible {
		associatedtype Lifted
		init(lifting value: Lifted)
	}
	
	prefix operator ^ {}
	prefix func ^ <Lifting: LiftingConvertible> (lifted: Lifting.Lifted) -> Lifting {
		return Lifting(lifting: lifted)
	}
	
	let myTree: Tree = [^1, [^2, ^three]]

That's actually not so bad.

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list