LoginSignup
10
10

More than 5 years have passed since last update.

1 / 10

関数を定義する & 呼ぶ

func increment(n: Int) -> Int {
    return n + 1
}

let increment = { (n: Int) in n + 1 }
let increment = { (n) in n + 1 }
let increment = { n in n + 1 }
let increment = { $0 + 1 }
increment(4)  // 5

関数を返す関数

「カリー化」された関数を定義する構文があるのだが、廃止予定 :disappointed:

func makeConst(n: Int)(_: Int) -> Int {
    return n
}

makeConst(4)(7)  // 4

今後は以下のようになる

func makeConst(n: Int) -> Int -> Int { 
    return { (_: Int) in n }
}

オプショナル

let m: Int? = nil
let n: Int? = 0

if let m = m, n = n {
    print(m + n)
}

二重のオプショナル

let p: Int?? = nil          // 外側が nil
let q: Int?? = nil as Int?  // 内側が nil
let r: Int?? = 0

ちなみに Haskell だと

p = Nothing
q = Just (Nothing)
r = Just (Just 0)

Map

let a: Int? = nil
let b: Int? = 2

a.map { n in n + 1 }  // nil
b.map { n in n + 1 }  // 3
let a = [0, 1, 2, 3, 4]
a.map { n in n * 2 + 1 }  // [1, 3, 5, 7, 9]
let s = Set([1, 2, 3])
s.map { x in x + 1 }  // [3, 4, 2]

集合も map すると配列になってしまう... :disappointed:


flatten

二重のリストを一重にする

[[1, 2], [3, 4]].flatten()
// [1, 2, 3, 4]

二重オプショナルの flatten はない :disappointed:


flatMap

map して flatten する

[10, 20, 30].flatMap { n in [n, n + 1] }
// [10, 11, 20, 21, 30, 31]
func divide10(n: Int) -> Int? {
    guard n != 0 else {
        return nil
    }
    return 10 / n
}

(nil as Int?).flatMap(divide10)  // nil
(0   as Int?).flatMap(divide10)  // nil
(5   as Int?).flatMap(divide10)  // 2

モノイドをプロトコルとして定義する

protocol Monoid {
    init()
    func + (left: Self, right: Self) -> Self
}

extension Int: Monoid {
}
extension Array: Monoid {
}

func reduce<S: SequenceType
        where S.Generator.Element: Monoid>
        (sequence: S) -> S.Generator.Element {
    return sequence.reduce(
        S.Generator.Element(), combine: +)
}

reduce([] as [Int])    // 0
reduce([] as [[Int]])  // []
reduce([0, 1, 2, 3])   // 6
reduce([[0, 1, 2], [3, 4], [5, 6, 7, 8]])
// [0, 1, 2, 3, 4, 5, 6, 7, 8]

Swift でできないこと :disappointed:

  • 末尾呼び出し最適化
    • 最適化器が頑張ればできることもある
  • ファンクターやモナドをプロトコルとして定義する
    • リストやオプショナルの mapflatMap はシグネチャーが「同じ」だけで、プロトコルとしては共通化されていない
10
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10