我正在尝试实现功能组合.起初我定义了一个名为compose的函数.
func compose<A,B,C>(f:(B -> C))(g: (A -> B)) -> A -> C { return { f(g($0)) } }
这非常有效.例如,如果我没有和isEven函数一样
func not(value: Bool) -> Bool { return !value } func even(value: Int) -> Bool { return value % 2 == 0 }
奇数函数可以用not来定义,甚至可以这样定义:
func odd(value: Int) -> Bool { return compose(not)(isEven)(value) }
然后我决定使用自定义运算符而不是compose函数.自定义操作符是……起初我刚刚复制了compose函数并将其名称更改为…以下是它的样子:
infix operator .. { associativity left } func ..<A,C>(f:(B -> C))(g: (A -> B)) -> A -> C { return { f(g($0)) } }
这里Xcode给出了错误:“一元运算符实现必须有’前缀’或’后缀’修饰符”
之后我将操作符更改为:
infix operator .. { associativity left } func ..<A,C>(f: (B -> C),g: (A -> B)) -> A -> C { return { f(g($0)) } }
奇怪的功能:
func odd(value: Int) -> Bool { return (not..even)(value) }
或者作为封闭:
let odd = not..even
这段代码很有效.现在我知道也许这里没有任何好处..操作符在这里讨好,但我想知道为什么不允许咖喱操作符?例如,如果运算符被定义为curried函数,我们将做这样的事情:
let array = [1,2,3,4] array.map((+1))
解决方法
您需要一些称为运算符部分的东西,或者能够在左侧或右侧部分应用二元运算符.不幸的是,Swift只允许完全没有问题的操作符,这意味着你必须要有一点创意.如果我们将运算符视为二元函数op:(A,A) – > A,然后它的咖喱形式,咖喱操作:A – > A – > A,只是一个返回一元函数的一元函数.我们可以使用分别模拟左右分区的自定义前缀和后缀运算符来伪装它.
这是前缀和后缀
prefix func +<A : protocol<IntegerLiteralConvertible,IntegerArithmeticType>>(r : A) -> (A -> A) { return { l in l + r } } postfix func +<A : protocol<IntegerLiteralConvertible,IntegerArithmeticType>>(l : A) -> (A -> A) { return { r in l + r } }
这允许您编写诸如此类的代码
let l = [Int](1...10) /// [1,4,5,6,7,8,9,10] l.map(+5) /// [6,10,11,12,13,14,15]
而不是旧的
l.map({ x in x + 5 })
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。