Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Swiftの関数の引数は、常に一つ

More than 5 years have passed since last update.

だとしたら、Swiftではカリー化は不要ということになってしまう。

すなわち、ざっくり言うとカリー化とは複数の引数を1つに減らすことを指します - Swiftで関数のカリー化(currying)入門

Swiftの関数は、つねに一つの値を受け取り、一つの値を返すのだから。

以下のコードを動かしてみれば、それがわかる。

func call<A,R>(f:A->R, a:A)->R {
    return f(a)
}
func id(i:Int)->Int { 
    return i
}
func add(x:Int, y:Int)->Int {
   return x + y
}
call(id, 42)       // 42
call(add, (21,21)) // 42

上記のcall()は、「『型Aの値を一つだけ取って型Rの値を返す関数』と『型Aの値』を取って『型Rの値』を返す関数」なはずなのに、「IntIntを取ってIntを返す」関数も受け取っている。

なぜか?

IntIntを取ってIntを返す」関数なんて、はじめからどこにもなかったからだ。

あったのは、

(Int, Int)を受け取ってIntを返す関数」

だったのだ。

全てのSwiftの関数は、tupleを一つだけ受け取る関数なのである。

Haskellの言葉で言えば、上記のadd()

add:: Integer -> Integer -> Integer

ではなく

add::  (Integer, Integer) -> Integer

ということになる。

add()の本当の姿は、

func add(arg:(Int,Int))->Int {
   let (x, y) = arg
   return x + y
}

だったわけだ。

ちなみに(Int, Int)は、Intとは独立した固有の型である。そしてInt(Int)でもある。ので要素数ゼロのtupleである()を除く全ての値は、必ず.0というプロパティが存在する。

let n = 0
n // 0
n.0 // 0
n.0.0 // 0
n.0.0.0 // 0
// ちなみに0.0.0... は syntax error
// さもないと 0.0がDouble(0.0)なのか(0).0なのか判別不能になる

さらに

func hello(){ println("hi") }

は、()を受け取って()を返す関数であり、

call(hello, ())

は期待通り動く。

The Swift Programming Languageには

Tuples are particularly useful as the return values of functions

なんてのんきに書いてあるが、便利どころかSwiftでは全ての値がtupleなのだ。通常の値は要素数1のtupleで、「値がない値」すら、要素数0のtuple。

このことを知らなくても、普通の関数やclassやstructやenumは書けるのけど、上記のようにジェネリクスを使う場合、このことは必須の知識となる。

大事なことなのにアマツバメ本にきちんと明記していないので、記事にした次第。

(Dan, Swift, Newbie)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away