Swiftのファンクターと高階関数について少し

コレクション


Objective-Cを使用してSwiftに切り替えた開発者は、Swiftがコレクションを操作するために提供する最も便利な機能に気づかずにはいられませんでした。 インデックスで範囲を使用する
let slice = array[1..<10] 
アイテムを初期化してコレクションに追加するための便利な構文、拡張性、そしてもちろん高階関数

フィルター


コレクションで最も一般的に使用される関数は、おそらくフィルターです。
 let alex = Person(name: "Alex", age: 23) let jenny = Person(name: "Jenny", age: 20) let jason = Person(name: "Jason", age: 35) let persons = [alex, jenny, jason] let jNamedPersons = persons.filter { $0.name.hasPrefix("J") } // [jenny, jason] 


減らす


あまり一般的ではありませんが、非常に表現力があり便利なのは、reduce関数です。
 let ages = persons.map{ Float($0.age) } let average = ages.reduce(0, +) / Float(persons.count) 


独自の高階関数を作成できますが、これは非常にエキサイティングです。
 func divisible(by numbers: Int...) -> (Int) -> Bool { return { input -> Bool in return numbers.reduce(true) { divisible, number in divisible && input % number == 0 } } } let items = [6, 12, 24, 13] let result = items.filter(divisible(by: 2, 3, 4)) // [12, 24] 


地図


ファンクターとモナドの機能概念は、Haskell言語から生まれました。 彼らは、モナドが何であるかを把握して理解することは不可能であり、さらにそれを説明することは不可能だと言います。 それでも、一時的にすべての困難を捨てて、本当に必要なものだけを自分自身に説明することができます。さらに深く掘り下げたい人は、Haskellを探索することから始められます。

したがって、簡単にするために、ファンクターはmap関数が適用されるコンテナーであり、モナドはflatMap関数が適用されるファンクターであると想定できます。

コレクションはコンテナであり、マップ関数はSwiftで定義されているため、コレクションはファンクタとして機能できます。
ある型のコレクションを別の型のコレクションに変換するには、人の配列を取得し、そこから型の年齢の配列を取得します[Int]
 let ages = array.map{ $0.age } // [23, 20, 35] 


フラットマップ


そして、モナドの役割において:
oprtional型の配列からオプションの値の配列を返すため
 let optionalStrings: [String?] = ["a", nil, "b", "c", nil] let strings = optionalStrings.flatMap { $0 } // ["a", "b", "c"] 

元のコレクションを展開するため
 let odds = [1,3,5,7,9] let evensAndOdds = odds.flatMap { [$0, $0 + 1] } // [1,2,3,4,5,6,7,8,9,10] 



オプショナル


ただし、mapとflatMapはコレクションだけでなく適用できます。 モナドとしてオプション型を使用すると、非常に便利です。

地図


Optionalに値がある場合、この値を持つmapの結果が返されます;値がない場合、nilが返されます:
 let name: String? = "World" let greeting = name.map { "Hello " + $0 + "!" } // "Hello World!" 

でも
 let name: String? = nil let greeting = name.map { "Hello " + $0 + "!" } // nil 


フラットマップ


FlatMapはほぼ同じように機能しますが、唯一の違いは、flatMapの動作の結果はnilを返すことができ、mapは

 let string: String? = "42" let number = string.flatMap { Int($0) } // 42 

しかし、文字列「42」では、Intは自分自身を初期化できません
Intはできませんが、Swiftは多くのことができます
 let formatter = NumberFormatter() formatter.numberStyle = .spellOut formatter.locale = Locale(identifier: "RU") let a = formatter.number(from: " ") 
// 42

 let string: String? = " " let number: Int? = string.flatMap { Int($0) } // nil 

マップを適用しようとすると
 let number: Int? = string.map { Int($0) } 
エラーを参照してください。

おわりに


オプション変数を操作するときにモナドとファンクターを使用すると、コードの量を大幅に削減し、視覚的にすることができます。

Source: https://habr.com/ru/post/J322806/


All Articles