11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift で Either

Last updated at Posted at 2015-01-10

追記

@autoclosure は呼び出すたびに評価されてしまうらしいので、Box を使う形に修正( yad さん、ご指摘有難うございました)
https://github.com/amo12937/amo.Either/tree/v1.1.0

git clone -b v1.1.0 git@github.com:amo12937/amo.Either.git

「2つの型のどちらか」を表すモナドを作った。

使い方

  • リポジトリをクローン
git clone -b v1.0.0 git@github.com:amo12937/amo.Either.git
  • xcode でビルド
  • Products/Either.framework を使いたいプロジェクトへコピー

仕様兼テスト

2つの型のどちらかを保持できる

EitherTests.swift
    func test_2つの型のどちらかを保持できる() {
        let n = 1
        let u = Either<Int, String>.Left(n)
        XCTAssertEqual(n, u.left()!)
        XCTAssertTrue(u.right() == nil)
        
        let s = "hoge"
        let v = Either<Int, String>.Right(s)
        XCTAssertTrue(v.left() == nil)
        XCTAssertEqual(s, v.right()!)
    }

coproductは返り値が同じ型の2つの関数からEither型を引数とする関数を返す

EitherTests.swift
    func test_coproductは返り値が同じ型の2つの関数からEither型を引数とする関数を返す() {
        var f_count = 0
        func f(b: Bool) -> String {
            f_count++
            return "\(b)"
        }
        
        var g_count = 0
        func g(n: Int) -> String {
            g_count++
            return "\(n)"
        }
        
        let u = Either.coproduct(f, g)
        
        let x = Either<Bool, Int>.bind(true)
        let y = Either<Bool, Int>.bind(1)
        
        XCTAssertEqual(0, f_count)
        XCTAssertEqual("true", u(x))
        XCTAssertEqual(1, f_count)
        
        XCTAssertEqual(0, g_count)
        XCTAssertEqual("1", u(y))
        XCTAssertEqual(1, g_count)
    }

bindはEitherのconstructorと同じ働きをする

EitherTests.swift
    func test_bindはEitherのconstructorと同じ働きをする() {
        let n = 1
        let u = Either<Int, String>.bind(n)
        XCTAssertEqual(n, u.left()!)
        XCTAssertTrue(u.right() == nil)
        
        let s = "hoge"
        let v = Either<Int, String>.bind(s)
        XCTAssertTrue(v.left() == nil)
        XCTAssertEqual(s, v.right()!)
    }

bindFuncは関数をbindする

EitherTests.swift
    func test_bindFuncは関数をbindする() {
        let l = ["a", "b", "c"]

        let f = {(a: [String]) -> Int in a.count}
        let u = Either<Int, String>.bindFunc(f)
        XCTAssertEqual(3, u(l).left()!)
        XCTAssertTrue(u(l).right() == nil)
        
        let g = {(a: [String]) -> String in "".join(a)}
        let v = Either<Int, String>.bindFunc(g)
        XCTAssertTrue(v(l).left() == nil)
        XCTAssertEqual("abc", v(l).right()!)
    }
11
11
2

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
11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?