Skip to content

Instantly share code, notes, and snippets.

@tarunon
Last active April 6, 2021 15:21
Show Gist options
  • Save tarunon/c45d76d8be9d01ce0ea074b69a586d6f to your computer and use it in GitHub Desktop.
Save tarunon/c45d76d8be9d01ce0ea074b69a586d6f to your computer and use it in GitHub Desktop.
Introducing `if statement` `for statement` into swift. Required swift 5.4.
public enum Either<L, R> {
case left(L)
case right(R)
}
@resultBuilder
public struct Expressive<T> {
public static func buildBlock<C>() -> C? { nil }
public static func buildBlock<C>(_ component: C) -> C { component }
public static func buildEither(first component: T) -> T { component }
public static func buildEither(second component: T) -> T { component }
public static func buildOptional<C>(_ component: C?) -> C? { component }
public static func buildArray<C>(_ components: [C]) -> [C] { components }
public static func buildEither<F, S>(first component: F) -> Either<F, S> { .left(component) }
public static func buildEither<F, S>(second component: S) -> Either<F, S> { .right(component) }
}
public func expressive<T>(leastCommon: T.Type = T.self, @Expressive<T> _ f: () -> T) -> T { f() }
public func expressive<T, R>(leastCommon: T.Type = T.self, @Expressive<T> _ f: () -> R) -> R { f() }
import XCTest
@testable import Expressive
protocol Animal {}
struct Cat: Animal {}
struct Dog: Animal {}
struct Bird: Animal {}
final class ExpressiveTests: XCTestCase {
func testTypeInferences() {
XCTAssertTrue(
expressive {
if true {
1
}
} is Optional<Int>
)
XCTAssertTrue(
expressive {
if true {
1
} else {
2
}
} is Int
)
XCTAssertTrue(
expressive {
if true {
Cat()
} else {
Dog()
}
} is Either<Cat, Dog>
)
XCTAssertTrue(
expressive {
if true {
Cat()
} else {
Dog()
}
} as Animal is Animal
)
XCTAssertTrue(
expressive {
for i in 0..<10 {
i
}
} is [Int]
)
XCTAssertTrue(
expressive {
for i in 0..<10 {
if i % 2 == 0 {
Cat()
} else {
Dog()
}
}
} is [Either<Cat, Dog>]
)
XCTAssertTrue(
expressive(leastCommon: Animal.self) {
for i in 0..<10 {
if i % 2 == 0 {
Cat()
} else {
Dog()
}
}
} is [Animal]
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment