LoginSignup
2

More than 5 years have passed since last update.

posted at

updated at

Swift 2.2 の新機能: SE-0014: AnySequence.init に制約を与える

今回は SE-0014: AnySequence.init に制約を与える です。Swift のシーケンスの実装を理解していないのでだいぶ怪しいです...
ツッコミお待ちしています。
原文に従ってこの訳は Apache License 2.0 とします。

SE-0014: AnySequence.init に制約を与える

はじめに

AnySequence がその子孫にあたる型に呼び出しをデリゲートできるよう、イニシャライザは追加の制約を持つべきです。

動機

現在のところ AnySequenceSequenceType プロトコルのメソッドに対する呼び出しをその子孫にあたる型を持つシーケンスにデリゲートしません。この結果、必要に応じてその場で動的にダウンキャストすることになります(SequenceType.dropFirst または SequenceType.prefix のデフォルトの実装を見てください)。さらに、こちらの方がより重要ですが、デリゲーション無しでは SequenceType のメソッドをカスタマイズした実装は無視されてしまうでしょう。

提案手法

このプルリクエストにある実装を見てください。

この種のデリゲーションを実現するには _SequenceBox はもとのシーケンスだけではなく SubSequence も 'ラップ' する必要があります。するとこのような宣言は:

internal class _SequenceBox<S : SequenceType>
    : _AnySequenceBox<S.Generator.Element> { ... }

このようになるでしょう:

internal class _SequenceBox<
  S : SequenceType
  where
    S.SubSequence : SequenceType,
    S.SubSequence.Generator.Element == S.Generator.Element,
    S.SubSequence.SubSequence == S.SubSequence
> : _AnySequenceBox<S.Generator.Element> { ... }

次に AnySequence.init には以下のような制約がつくことになるでしょう。

変更前:

public struct AnySequence<Element> : SequenceType {
  public init<
    S: SequenceType
    where
      S.Generator.Element == Element
  >(_ base: S) { ... }
}

変更後:

public struct AnySequence<Element> : SequenceType {
  public init<
    S: SequenceType
    where
      S.Generator.Element == Element,
      S.SubSequence : SequenceType,
      S.SubSequence.Generator.Element == Element,
      S.SubSequence.SubSequence == S.SubSequence
  >(_ base: S) { ... }
}

私たちは全ての SequenceType の実装がこれらの制約を最初から満たしていてほしいと思います。するとこれらの制約は実際のところ SequenceType プロトコル自体に適用されるべきなのです(現在のところそれは不可能なのですが)。技術的には S.SubSequence.SubSequence == S.SubSequence は必ずしも必要ではないという点は触れておく価値があります。これは同じ型を要素に持つシーケンスは全てこの制約を満たしているからです。しかし現在のところそれを表現する方法はありません。

既存のコードに対する影響

全ての SequenceType プロトコルに準拠する組み込み型は基本的に (SubSequence.SubSequence == SubSequence) という関係を持つように作られるので、新しい制約が影響を与えることはありません。サードパーティーのコレクションも、もしデフォルトの SubSequence (例えば Slice)を使っていたとしても問題ないはずです。カスタムの SubSequence を持つ型はそのプロトコルに準拠しなくなるかもしれません。

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
What you can do with signing up
2