3

我在 Swift 2.1 中搞乱了函数式编程,试图实现Church 编码对/cons函数(cons = λx λy λf fxy in untyped lambda calculus),我读过这在早期版本的 Swift 中无法完成。

使用泛型它看起来像

func cons<S,T,U>(x:S,_ y:T) -> ((S,T) -> U) -> U
{
    return { (f:((S,T) -> U)) -> U in return f(x,y)}
}

cons(1,2)
//error: cannot invoke 'cons' with an argument list of type '(Int, Int)'
//note: expected an argument list of type '(S, T)'

这不起作用,并给出了我无法理解的错误(类型(Int,Int)的参数列表肯定可以匹配泛型类型变量(S,T)?)

如果您摆脱泛型类型,并将它们全部声明为 Ints,则该函数可以工作,但是我们当然希望能够将长度超过 2 的列表组合在一起;例如,使用长度为 3 的列表是使用 (Int,Int) -> Int 来使用 Int。

另一种选择是将所有内容输入为Any(请参阅Type Casting for Any 和 AnyObject),但我也无法做到这一点。

你有什么想法?这在 Swift 中是否可行?我确信有更简单的方法来实现cons/ car/ cdr,但我对 Church 编码特别感兴趣,其中列表元素是匿名函数 (lambdas) 的参数。

4

1 回答 1

1
func cons<S,T,U>(x:S,_ y:T) -> ((S,T) -> U) -> U
{
    return { (f:((S,T) -> U)) -> U in return f(x,y)}
}

let i: ((Int,Int)->Int)->Int = cons(1,2)
let d: ((Int,Int)->Double)->Double = cons(2,3)
let e: ((Double,Int)->String)->String = cons(2.2, 1)
let e: ((Double,Int)->Double)->Double = cons(2.2, 1)

仍然有一种类型是“额外”类型,编译器无法推断。如果您定义类型,您可以看到,并非所有组合都是有效的。只需定义输出类型,编译器应该会很高兴

func cons<S,T, U>(x:S,_ y:T, outptAs: U.Type) -> ((S,T) -> U ) -> U
{
    return { (f:((S,T) -> U)) -> U in return f(x,y) }
}

let i = cons(1.2 ,"A", outptAs: Int.self)
let j = cons("alfa","beta", outptAs: Double.self)
于 2015-11-08T18:17:44.990 回答