LoginSignup
17
17

More than 5 years have passed since last update.

吾輩はCompound Typeである 〜 タプル型と関数型の正体を探る

Last updated at Posted at 2016-07-12
1 / 42

image


image


Extensionの好循環 のコピー.png


image


関数型やタプル型にExtensionを書く方法は?


Not Found

The requested way not found in this language.


image


型(Type)


型(Type)

  • named type
  • compound type

Type > named type


named type

= 固有の名前を与えて定義できる型

  • class type
  • struct type
  • enum type
  • protocol type

だいたいの型は、named type

public struct Array<Element> :
 CollectionType, MutableCollectionType, _DestructorSafeContainer
public struct Dictionary<Key : Hashable, Value> :
 CollectionType, DictionaryLiteralConvertible
public enum Optional<Wrapped> :
 _Reflectable, NilLiteralConvertible

名前がある=extendできる


Type > compound type


compound type

= 名前のない型

  • tuple type
  • function type

名前がない=extensionも書けない


Type > compound type > tuple type


tuple type

括弧で囲まれた、
0個以上の型のカンマ区切りリスト

(Melon, String, Bool)

tuple type

 
コロンで要素名をつけられる

(melon: Melon, farmName: String, isTasty: Bool)

let tuple = (
    melon: Melon(),
    farmName: "夕張",
    isTasty: true
)

スクリーンショット 2016-07-10 13.41.47.png


ちなみに、型Tをひとつだけもつタプルは型Tと同じ扱いになります

// 1個の要素をもつタプルに、タプルでない型を代入可能
let p: ((Int)) = 1
// ※ 型は let p: ((Int)) タプル型だと認識されている

// タプルでない型に、1個の要素をもつタプルを代入可能
let r: String = (((("a"))))
// ※ 型は let r: String

// タプルの存在を意識せず比較も可能
let f: ((((((Int))))) -> (((((((((String))))))))))
    = { return $0 == p ? r : r }
// ※ 関数の型は書いたとおりに
// let f: ((((((Int))))) -> (((((((((String)))))))))) になっている

Type > compound type > function type


突然ですがここでクイズです

() -> Void

Q. この関数型の、引数・戻り値は?
 


突然ですがここでクイズです

() -> Void

Q. この関数型の、引数・戻り値は?

A. 何も引数に取らず、何も返さない関数?


🙅


() -> Void

Q. この関数型の、引数・戻り値は?

正解:

空タプルを引数に取り、空タプルを返す関数


function type

image


function type

image

() -> Void

function type

image

() -> Void

image


function type

image

() -> Void

つまり、

  • parameter type: ()
  • return type: ()

検証してみよう

func hoge() {}

let p = ()
let r = hoge(p)
print(r)


検証してみよう

func hoge() {}

let p = ()
let r = hoge(p) // ←空タプルを引数として渡せる
print(r) // ()   ←空タプルを戻り値として受けられる


そう考えると…

(Int) -> Melon
([Melon]) -> Melon?
(melon: Melon, farmName: String, isTasty: Bool) -> Melon?

関数の引数って、タプルに見えてきませんか?


というか、実際タプルなんです。


func taste(melon: Melon, farmName: String, isTasty: Bool) {
    print(farmName + "の🍈は" + (isTasty ? "おいしい" : "まずい"))
}

let tuple = (melon: Melon(), farmName: "夕張", isTasty: true)

//実際Swift2ではこれで通ったりする
taste(tuple)

Swift3では関数の引数にタプルを渡すのはエラーになるけど、一段抽象化すると、通る。

func taste(melon: Melon, farmName: String, isTasty: Bool) {
    print(farmName + "の🍈は" + (isTasty ? "おいしい" : "まずい"))
}

let tuple = (melon: Melon(), farmName: "夕張", isTasty: true)

//taste(tuple)
// Error: passing 3 arguments to a callee as a single tuple value has been removed in Swift 3
// see also: https://github.com/apple/swift/blob/master/test/Misc/misc_diagnostics.swift#L136

func apply<P, R>(to function: (P) -> R, parameter: P) -> R {
    return function(parameter)
}

apply(to: taste, parameter: tuple)

function typeを
parameter type -> return type という
シンプルなcompound typeとして表現するために、
tuple というcompound typeが役に立っているようだ


まとめ

compound typeを理解すると、型の世界がもっとよく理解できる!


で、結局、何故compound typeに対してはExtensionが書けないのかって?

…。


で、結局、何故compound typeに対してはExtensionが書けないのかって?

…。

…何故でしょうね?
何か分かる方いらっしゃったらお話しましょう!


参考

The Swift Programming Language (Swift 2.2): Types
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html

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