Notasi scala infix

12

Apakah mungkin untuk memanggil metode menggunakan notasi infix?

Misalnya, di Haskell, saya bisa menulis fungsi berikut:

x `isAFactorOf` y = x % y == 0

dan kemudian gunakan seperti:

if 2 `isAFactorOf` 10 ...

Yang dalam beberapa kasus memungkinkan untuk kode yang sangat mudah dibaca. Apakah ada yang serupa dengan ini di Scala? Saya mencari "notasi Scala infix", tetapi istilah itu sepertinya berarti sesuatu yang berbeda dalam Scala.

Carcigenicate
sumber

Jawaban:

15

Dimulai dengan versi 2.10, Scala memperkenalkan Kelas implisit untuk menangani masalah ini dengan tepat.

Ini akan melakukan konversi implisit pada jenis yang diberikan ke kelas terbungkus, yang dapat berisi metode dan nilai Anda sendiri.

Dalam kasus spesifik Anda, Anda akan menggunakan sesuatu seperti ini:

implicit class RichInt(x: Int) {
  def isAFactorOf(y: Int) = x % y == 0
}

2.isAFactorOf(10)
// or, without dot-syntax
2 isAFactorOf 10

Perhatikan bahwa saat dikompilasi, ini akan berakhir dengan meninju nilai mentah kita menjadi a RichInt(2). Anda dapat menyiasatinya dengan mendeklarasikan RichInt Anda sebagai subkelas dari AnyVal:

implicit class RichInt(val x: Int) extends AnyVal { ... }

Ini tidak akan menyebabkan tinju, tetapi lebih ketat daripada kelas implisit yang khas. Itu hanya dapat berisi metode, bukan nilai atau status.

KChaloux
sumber
2
Anda mungkin harus menyebutkan bahwa kelas implisit tidak dapat menjadi level atas, sehingga kelas implisit perlu didefinisikan secara lokal.
Carcigenicate
3

Pada dasarnya, di Scala Anda tidak dapat memanggil fungsi dengan cara infiks, tetapi Anda dapat mendefinisikan metode pada tipe, yang argumen kiri dapat dikonversi secara implisit. Jadi untuk contoh Anda, Anda dapat mendefinisikan kelas yang memiliki metode isAFactorOf (mengambil Int) dan menunjukkan bahwa Int dapat secara implisit dikonversi ke turunan dari kelas ini.

Jika Anda melihat jawaban ini /programming//a/3119671 untuk pertanyaan lain, Anda akan melihat sintaks dalam Scala yang berfungsi setara.

persamaan
sumber
Itu worth menunjukkan bahwa versi baru dari Scala memiliki konstruk secara eksplisit untuk ini, yang jawabannya terkait tidak alamat: implicit class RichInt(i: Int) { def square() = i * i }.
KChaloux