Last active
August 29, 2015 14:04
-
-
Save rnapier/8eda179689d9d61c2bfb to your computer and use it in GitHub Desktop.
And autoclosure saves(?) the day for generic recursive enums
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Creating a generic recursive data structure with autoclosure. (READ ALL NOTES; THIS MAY NOT DO WHAT YOU WANT.) | |
// Closures are reference types, so the size is known (? I think ?) | |
// Note that this is just because of unimplemented features in the compiler in Beta5 | |
// There's no reason to think this is a long-term requirement. | |
// IMPORTANT: the closure will run every time you access this value, so if that has | |
// side effects, this won't work. It's only possible on pure value types. | |
// But the fact that this works as expected is actually kind of incredible. | |
// Think about what is required for it to work out the type for NestedList.Elem("first"). | |
// Yet Xcode still has no idea where to put the }. | |
enum NestedList<A> { | |
case Elem(@autoclosure ()->A) // <--- The magic | |
case List([NestedList]) | |
var description: String { | |
switch self { | |
case let Elem(x): return reflect(x()).summary | |
case let List(list): return "[" + join(", ", list.map{ $0.description }) + "]" | |
} | |
} | |
} | |
let first = NestedList.Elem("first") | |
let second = NestedList.Elem("second") | |
let list = NestedList.List([first, second]) | |
let outerlist = NestedList.List([first, list]) | |
println(first.description) | |
println(list.description) | |
println(outerlist.description) | |
// I (correctly) won't compile because of type mismatch | |
// let bad = NestedList.List([first, NestedList.Elem(2)]) | |
// For more fun, we can replace the array with a varadic, | |
// but notice how it becomes a tuple of an array rather than an array (https://devforums.apple.com/thread/239744) | |
enum NestedList { | |
case Elem(String) | |
case List(NestedList...) // <=== | |
var description: String { | |
switch self { | |
case let Elem(text): return text | |
case let List(list): return "[" + join(", ", list.0.map{ $0.description }) + "]" | |
} | |
} | |
} | |
let first = NestedList.Elem("first") | |
let second = NestedList.Elem("second") | |
let list = NestedList.List(first, second) // <=== no more [] | |
let outerlist = NestedList.List(first, list) | |
first.description | |
list.description | |
outerlist.description |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment