0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Swift】Partial application of 'mutating' method is not allowedってなんだ

Last updated at Posted at 2019-12-18

structを使っていたら、

Partial application of 'mutating' method is not allowed

というエラーに遭遇しました。
僕の場合、原因は別件だったんですが、日本語情報があまりないエラーメッセージだったので、記事にしてみます。

僕のエラーの原因

僕の場合、

protocol aDelegate {
    var aView: ViewClass
}

struct AStruct {
    
    private weak var delegate: aDelegate?

    private mutating func aFuncation() {
        switch aView.aVariable { //この行で"Partial application of 'mutating' method is not allowed"
        case .any
            //any
        default:
            //any
        }
    }
}

という書き方をしたらこのエラーが出ました。

switch aView.aVariable

ここを

switch delegate?.aView.aVariable

とすればOKでした。

それで終わりなんですが、ついでなんでエラーメッセージの意味も調べてみました。

Partial application of 'mutating' method is not allowedってなんだ

Partial application

Partial applicationは、日本語にすると部分適用と訳される技術用語です。
関数型プログラミングっぽい用語で、日本語記事見ると、だいたいカリー化と一緒に紹介されている用語です。
複数の引数を持った関数に対して、普通は全変数に値を渡して、戻り値を得ます。
たとえば、f(a,b,c) = a + b + c という関数があったら、f(1,1,1) = 1 + 1 + 1 = 3 ですね?
これを部分適用だと、

f(a,b,c) = f(a, 1, 1) = f(a) + 2 = f(1) + 2 = 3
ただしf(a) = a, f(b, c) = b + c

みたいな計算ができます。
命令形言語使ってると、「何が嬉しいんだ……?」という気になりますが、
関数型言語だと関数が汎用的なので、利便性のために汎用性を減らしたいときがあるみたいです。

Partial application of 'mutating' method is not allowedの例

Partial application of 'mutating' method is not allowed

エラーメッセージでググったら一番上に出てくるのがこちらの記事。

struct MyStruct {
    var count = 0

    mutating func add(amount: Int) {
        count += amount
    }
}

var myStruct = MyStruct()

[1, 2, 3, 4].forEach(myStruct.add)
// Partial application of 'mutating' method is not allowed

想定している結果としては、1+2+3+4でcount=10となるのを想定していると思われます。
そもそもforEachの中にカッコ省略してメソッド書いて動くのか……?とかはあるんですが、とりあえず"Partial application of 'mutating' method is not allowed"でエラー。
記事の中でも動くコードの例は出てますが、下記でも動きます。

動く例
var count = 0
[1, 2, 3, 4].forEach({ amount in count += amount })
print(count) //10

なぜこれがエラーになるかというと、内部的には

myStruct.add(1)

myStruct.add(2)

myStruct.add(3)

myStruct.add(4)

myStruct.add(1,2,3,4) ※この関数の場合ここでは何もせず

という順番で処理する必要があり、これが部分適用になる訳ですね。

Swiftで部分適用?

Swiftで部分適用(カリー化)にある、

func addTwoNumbers(a: Int)(b: Int) -> Int {
  return a + b
}

let add1 = addTwoNumbers(1)
add1(b: 2) //< 3

という書き方がその昔Swiftオフィシャルでできたらしいのですが、Swiftいくつからなのかは不明ですが、廃止されました。

0
2
0

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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?