phantom type

phantom type

👻

3925ee6eaa41031bac799de0f4f528ec?s=128

to4iki

May 21, 2017
Tweet

Transcript

  1. Phantom Type shinjyuku.lt #8 @to4iki

  2. People • @to4iki • GANMA!ͱ͍͏ອըͷαʔϏεΛ࡞ͬͯ ·͢ • ࠷ۙͷϑΝγϦςʔγϣϯʹڵຯ͕͋Δ • ޷͖ͳ৯΂෺͸Ͱ͢

    • ੴ֞ౡʹߦͧ͘ʂ
  3. None
  4. ΍Γ·͢ https://builderscon.io/tokyo/2017

  5. ϘϥϯςΟΞελοϑ ืू͍ͯ͠ΔΑʂ

  6. Agenda • Phantom Type ͱ͸ • ࣮༻ྫ

  7. Phantom Type

  8. Phantom Typeͱ͸#1 • ܕݕࠪΛར༻ͨ͠σβΠϯύλʔϯ • Haskell΍Scalaք۾ͳͲͰطʹྺ࢙ͷ͋Δύ λʔϯ

  9. Phantom Typeͱ͸#2 • Πϯελϯεͷঢ়ଶΛ஋Ͱ͸ͳ͘ܕύϥϝʔλͱ͠ ͯ࣋ͭ͜ͱͰɺঢ়ଶνΣοΫΛ࣮ߦ࣌Ͱ͸ͳ͘ίϯ ύΠϧ࣌ʹߦ͏ • => ܕͦͷ΋ͷʹঢ়ଶΛ౰ͯࠐΉ •

    ݟͨ໨্ݱΕͳ੍͍໿ɺ࢖ΘΕͳ͍ܕ • => Έ͍ͨͳܕ
  10. ৚݅Λຬͨ͞ͳ͍ͱ ढ͍(ίϯύΠϧΤϥʔ) Λ͔͚Δ

  11. ৚݅Λຬͨ͢ͱ ੒෹͠ফ͑ڈΔ

  12. None
  13. example.

  14. ঢ়ଶΛઃܭ͢Δ // ૢ࡞ঢ়ଶΛදݱ͢ΔI/F protocol OperationState {} // ૢ࡞ঢ়ଶຖͷΫϥεఆٛ class Init:

    OperationState {} class Prepared: OperationState {}
  15. ঢ়ଶຖͷػೳΛઃܭ͢Δ // ܕύϥϝʔλͰঢ়ଶΛද͢ class HogeOperation<State: OperationState> {} // ঢ়ଶຖʹػೳΛઃܭ͢Δ extension

    HogeOperation where State == Init { func prepared() -> HogeOperation<Prepared> { return HogeOperation<Prepared>() } } extension HogeOperation where State == Prepared { func execute() { print("do something") } }
  16. ঢ়ଶʹԠͯ͡ɺػೳ͕੾ΓସΘΔ // ४උঢ়ଶ let operation = HogeOperation<Init>() operation.execute() // compile

    error // ४උ׬ྃঢ়ଶ let preparedOperation = operation.prepared() preparedOperation.execute() preparedOperation.prepared() // compile error
  17. ࣮༻ྫ

  18. ࣄલ࣮ߦΛڧ੍͢ΔBuilder // builderͷঢ়ଶ protocol BuilderState {} class Buildable: BuilderState {}

    class Unbuildable: BuilderState {} class UserBuilder<Name: BuilderState, Age: BuilderState> { fileprivate let name: String fileprivate let age: UInt private init(name: String, age: UInt) { self.name = name self.age = age } static var builder: UserBuilder<Unbuildable, Unbuildable> { return UserBuilder<Unbuildable, Unbuildable>(name: "", age: 0) } func set(name: String) -> UserBuilder<Buildable, Age> { return UserBuilder<Buildable, Age>(name: name, age: age) } func set(age: UInt) -> UserBuilder<Name, Buildable> { return UserBuilder<Name, Buildable>(name: name, age: age) } }
  19. ࣄલ࣮ߦΛڧ੍͢ΔBuilder struct User { let name: String let age: UInt

    } // NameͱAge͕Buildableͷ࣌ extension UserBuilder where Name: Buildable, Age: Buildable { funsc build() -> User { return User(name: name, age: age) } }
  20. ࣄલ࣮ߦΛڧ੍͢ΔBuilder let builder = UserBuilder<Unbuildable, Unbuildable>.builder builder.set(name: "hoge").build() // compile

    error builder.set(age: 10).build() // compile error let user = builder .set(name: "hoge") .set(age: 10) .build()
  21. Conclusion • PhantomTypeΛ࢖͏͜ͱͰɺܕύϥϝʔλʔ ʹΑΓΦϒδΣΫτͷৼΔ෣͍ʹ੍໿Λ༩͑ Δ͜ͱ͕Ͱ͖Δ • ܕύϥϝʔλʔ͕ҧ͑͹࣮ଶ͸ҟͳΔ • ίϯύΠϥʹΑΔঢ়ଶνΣοΫͷݕࠪΛߦ͏ ͜ͱ͕Ͱ͖Δ

  22. See also • http://qiita.com/taketo1024/items/71e3272211f08d7e0cde • https://www.slideshare.net/tomohirokumagai54/phantom-kbkztech • https://www.objc.io/blog/2014/12/29/functional-snippet-13-phantom- types/

  23. Any Questions?