在swift中使用高阶函数

时间:2017-06-27 15:27:54

标签: ios swift haskell

我正在学习从Haskell背景中快速学习,我想将这一点翻译成swift:

match :: Int -> Bool
match = (>) 3

hasMatch :: (Int -> Bool) -> [Int] -> [Int]
hasMatch pred ns = filter pred ns

hasMatch match [1..5] = [4,5]
我知道愚蠢的例子。这就是我对swift的看法:

func hasMatch(pred : (Int) -> Bool, ns : [Int]) -> [Int]{
    return ns.filter{n in pred(n:n)}
}


func match(n: Int) -> Bool{
    return n > 3
}

let os = hasMatch(pred : match, ns: [1,2,3,4,5])

哪个不编译。这是错误消息:

let os = hasMatch(pred : match, ns: [1,2,3,4,5])

    ./hello-swift.swift:48:28: error: extraneous argument label 'n:' in call
        return ns.filter{n in pred(n:n)}
                                  ^~~

./hello-swift.swift:48:24: error: closure use of non-escaping parameter 'pred' may allow it to escape
        return ns.filter{n in pred(n:n)}
                              ^
./hello-swift.swift:47:15: note: parameter 'pred' is implicitly non-escaping
func hasMatch(pred : (Int) -> Bool, ns : [Int]) -> [Int]{
              ^
                     @escaping 

我有两个问题:

  1. 我有pred(n:n),但这假定pred将其输入命名为n,这没有意义。所有功能都必须有命名输入吗?

  2. 如何更改代码以便编译

2 个答案:

答案 0 :(得分:3)

func hasMatch(pred: (Int) -> Bool, ns: [Int]) -> [Int] {
    return ns.filter { n in pred(n) }
}

如果函数是闭包,则不需要参数名称。

@escaping是swift中的一个关键字,告诉编译器传入函数将转义当前作用域,因此它需要保留/释放传入的参数(Swift,就像objective-c一样,使用保留计数用于内存管理)

但是,在这种情况下你不需要它 - 该错误是编译器抛出的红色鲱鱼,因为它无法用filter编译该行,所以它没有&#39知道你是否需要逃避。看起来它可以安全地运行:)

只要您删除了n:并且它可以解决您呼叫的filter,就会知道因为filter不需要@escaping关闭,你的方法不会让错误消失。

答案 1 :(得分:0)

func mapedData(){
let bookData = ["book1":120, "book2": 150]
let mapedData = bookData.map({(key,value) in return value + 40 })
print(mapedData)
}

// [160,190]

func filterData()
{
     let bookData = ["book1":127, "book2": 150 ,"book3": 289 ,"book4": 190, "book5": 950  ]
    let filterData = bookData.filter({(key,value) in return value < 200})
    print(filterData)
}

// [[book2]:150,“ book4”:190,“ book1”:127]

func reducedData()
{
    let data = [1,2,3,4,5,6,7,8,9,10]
    let reducedData = data.reduce(0, { sum , number in return sum + number })
    print(reducedData)
}

// 55

func compactData(){
       let data = [1,nil,3,4,5,6,7,nil,9,10]
    let cMap = data.compactMap({return $0})
    print(cMap)
}
// [1, 3, 4, 5, 6, 7, 9, 10]

func flatMappedData(){
    let data = ["sachin"]
    let characters = data.flatMap({return $0})
    print(characters)        
}

// [“ s”,“ a”,“ c”,“ h”,“ i”,“ n”]