LoginSignup
1
1

More than 5 years have passed since last update.

filterでプレイスホルダー複数使いたい

Posted at

filterでプレイスホルダー複数使いたい

(1 to 10).filter(_ % 3 == 0 || _ % 5 == 0).mkString(",")
// => 3,5,6,9,10

みたいな。

でもこれはコンパイルを通らない。

error: missing parameter type for expanded function
  ((x$1, x$2) => x$1.$percent(3).$eq$eq(0).$bar$bar(x$2.$percent(5).$eq$eq(0)))

と怒られる。


↓これならコンパイル通る。

(1 to 10).filter((it: Int) => it % 3 == 0 || it % 5 == 0).mkString(",")

でも、違うんだよ。
空気読んでくれよ。
引数の型とか、いちいち書きたくないよ。


コンパイラのエラーメッセージを読むと「引数の型がない」と言ってるが
よく見ると【引数を2つ取る関数】だと判断しているように見受けられる。

(x$1, x$2) => x$1.$percent ...

じゃ、これでどうよ。

implicit def dblArgs[A, B](f: (A, A) => B): (A) => B = (a: A) => f(a, a)

(1 to 10).filter(dblArgs(_ % 3 == 0 || _ % 5 == 0)).mkString(",")
// => 3,5,6,9,10

(1 to 10).filter(_ % 3 == 0 || _ % 5 == 0).mkString(",")
// => error: missing parameter type for expanded function ...

自分で書けばOKだが、暗黙には変換してくれない。。。


これならどうだ。

implicit class SeqW[A](seq: Seq[A]) {
  def filter(f: (A, A) => Boolean): Seq[A] = seq.filter(it => f(it, it))
}

(1 to 10).filter(_ % 3 == 0 || _ % 5 == 0).mkString(",")
// => error: missing parameter type for expanded function ...

ダメでした。。。

では、これなら?

implicit class SeqW[A](seq: Seq[A]) {
  // 名前をfilterNにしてみた
  def filterN(f: (A, A) => Boolean): Seq[A] = seq.filter(it => f(it, it))
}

(1 to 10).filterN(_ % 3 == 0 || _ % 5 == 0).mkString(",")
// => 3,5,6,9,10

OK!


どうやら同名の関数がある場合は暗黙変換は適用されないようだ。
implicit classでオーバーロードはできないってことか?
、、、と思いそうになったが調べてみると違った。
オーバーロードできます。
でも今回のケースではうまくいかない。
この件は後日メモを残す(つもり)


当初の目的は達成したものの、プレイスホルダーが増えれば増えた分だけfilterXを定義しなければならない。
最大で22個も。。。

しかもmapでも同じことやりたい、findでも、となると全部書くことに。。。

費用対効果が。。。


今回の件で、複数のプレイスホルダーを使うにはいろいろ面倒だ、ということがわかった。
ひとつ利口になった(といいなぁ)。

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