Skip to content

Instantly share code, notes, and snippets.

@lazyvar
Created August 14, 2018 11:53
Show Gist options
  • Save lazyvar/947b9e26b54c7fca37af67beca762a3e to your computer and use it in GitHub Desktop.
Save lazyvar/947b9e26b54c7fca37af67beca762a3e to your computer and use it in GitHub Desktop.
import UIKit
/* attempt 1 */
protocol HasApply { }
extension HasApply {
func apply(_ applying: (Self) -> Void) -> Self {
applying(self)
return self
}
}
extension NSObject: HasApply { }
let imageView = UIImageView().apply {
$0.contentMode = .scaleAspectFill
$0.layer.cornerRadius = 4
}
assert(imageView.contentMode == .scaleAspectFill)
assert(imageView.layer.cornerRadius == 4)
/* attempt 2 */
typealias ApplyFunction<T> = (T) -> Void
protocol HasApply2 { }
extension HasApply2 {
func apply2(_ applyFunctions: ApplyFunction<Self>...) -> Self {
for applyFunction in applyFunctions {
applyFunction(self)
}
return self
}
}
extension NSObject: HasApply2 { }
func setContentMode(_ contentMode: UIViewContentMode) -> ApplyFunction<UIImageView> {
return {
$0.contentMode = contentMode
}
}
func setCornerRadius(_ cornerRadius: CGFloat) -> ApplyFunction<UIImageView> {
return {
$0.layer.cornerRadius = cornerRadius
}
}
let imageView2 = UIImageView().apply2 (
setContentMode(.scaleAspectFill),
setCornerRadius(4)
)
assert(imageView2.contentMode == .scaleAspectFill)
assert(imageView2.layer.cornerRadius == 4)
/* attempt 3 */
infix operator &&&
extension HasApply2 {
func apply2(_ applyFunctions: [ApplyFunction<Self>]) -> Self {
for applyFunction in applyFunctions {
applyFunction(self)
}
return self
}
}
func &&&<T: HasApply2>(lhs: T, rhs: [ApplyFunction<T>]) -> T {
return lhs.apply2(rhs) // this does not compile?!
}
let imageView3 = UIImageView() &&& [
setContentMode(.scaleAspectFill),
setCornerRadius(4)
]
assert(imageView3.contentMode == .scaleAspectFill)
assert(imageView3.layer.cornerRadius == 4)
/* attempt 4 */
precedencegroup ForwardApply {
associativity: left
higherThan: LogicalConjunctionPrecedence
}
infix operator &> : ForwardApply
func &> <T>(lhs: T, rhs: (T) -> Void) -> T {
rhs(lhs)
return lhs
}
let imageView4 = UIImageView()
&> setContentMode(.scaleAspectFill)
&> setCornerRadius(4)
assert(imageView4.contentMode == .scaleAspectFill)
assert(imageView4.layer.cornerRadius == 4)
@lazyvar
Copy link
Author

lazyvar commented Aug 14, 2018

tl ; dr

let imageView = UIImageView().apply {
    $0.contentMode = .scaleAspectFill
    $0.layer.cornerRadius = 4
}

let imageView2 = UIImageView().apply2 (
    setContentMode(.scaleAspectFill),
    setCornerRadius(4)
)

let imageView3 = UIImageView() &&& [
    setContentMode(.scaleAspectFill),
    setCornerRadius(4)
]

let imageView4 = UIImageView()
    &> setContentMode(.scaleAspectFill)
    &> setCornerRadius(4)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment