Swiftは関数型の型推論にどのくらい耐えられるのか

  • 10
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

Swiftを書いていらっしゃる方なら、型推論が弱くて困る経験をされたことがあるかもしれません。

Expression was too complex to be solved in reasonable time

最近↑に愛着湧いてきました。嘘です。

気になったので、Swiftに関数型の型推論を少しずつ食わせていってどこで潰れるか少しだけ試してみることにします。

実験道具

さっきわたしが拾ってきたものを使う。

Argoはjsonのパースをするものである。結果が enumの Decoded<T> であり、functor( <^> )とapplicative( <*> )と、それから map / flatMap を使うと楽しい。
詳しい話は色々な方がすでにされているので省略。

題材

次のようなものをつくってビルドが通るか試す。

struct Hoge {
    let args0: String
    let args1: String
    //略
    let argsN: String

    static func create(args0: String)(args1: String)/*以下略*/(argsN: String) -> Hoge {
        return Hoge(args0: args0, args1: args1, /*以下略*/, argsN: argsN)
    }
}

extension Hoge: Decodable {
    static func decode(json: JSON) -> Decoded<Hoge> {
        return create
            <^> json <| "args0" // Functor
            <*> json <| "args1" // Applicative
            // 以下ずっとApplicative
            <*> json <| "argsN"
    }
}

実験開始

https://github.com/S-Shimotori/SwiftTypeInference
紙面の都合上省略して掲載します

ひたすらApplicative

↑に let argsN: String を増やすだけ。
引数14個までOK。15個目で力尽きた。

mapとApplicative

↑の json <| "argsN" を全部 (json <|? "argsN").map { $0 ?? "default" } に変えて、やはり増やす。
引数13個までOK。Applicativeのみの時と比べると1個減っただけだが、ビルドにものすごく時間がかかる。

AlternativeとApplicative

map ではなくAlternative( <|> )でやってみる。

json <| "argsN" <|> json <| "argsN_1"

<|> の右が pure("") であるぶんには14個まで行けるが、 <| だと7個まで。

数が半減した割には map より処理も諦めも早い。

入れ子状態

次のようなものを増やす。

struct Hoge {
    struct Nested {
        let args0: String
        let args1: String

        static func create(args0: String)(args1: String) -> Nested {
            return Nested(args0: args0, args1: args1)
        }
    }
}

でもって引数の型を Hoge.Nested にし、 json <| "argsN"

(Hoge.Nested.create <^> json <| ["nestedN", "args0"] <*> json <| ["nestedN", "args1"])

に変えてみる。
6個までOK。

まとめ

まあこんなもんですよね。
thoughtbot, inc.はCurryも出してるけど、到底アレは使い切れない。

個人的な感想

今年はついにオープンソース化されたし、来年は色々カンファレンスも控えてワクワクしますね。

わたしはいままで初心者本レベルのプログラミングしかしてなかったし、それもCやJavaといった既に安定した言語だったので、発表→β版→仕様変更の嵐という時代の流れを楽しみながらやってます。Swiftは安定してないからとまだ様子見の方も多いでしょうが、そういう楽しみ方も人生に1回くらい……なんて。