9

İstediğim şekilde davranamayacağım bir kod parçam var. (Bunun için soyunmuş) şu şekilde tanımlanan bir sınıf var:Birden çok parametre kapatma argümanı türü çıkarılamıyor

class Behaviour[T](private val rule: Time => T) { 
    def map1[U, V](behaviour: Behaviour[U], func: (T, U) => V): Behaviour[V] = { 
    new Behaviour(time => func(this.at(time), behaviour.at(time))) 
    } 
} 

ben önemsiz olacağını düşündüm bir şey çalıştı bu sınıfın uğraşırken: Geçen İçin

val beh = Behaviour(time => 5) 
val beh2 = Behaviour(time => 5) 
beh.map1(beh2, (a, b) => a + b) 

satır aşağıdaki hatayı alırsınız:

<console>:13: error: missing parameter type 
      beh.map1(beh2, (a, b) => a + b) 
          ^

tabii kapatma parametre türlerini belirtebilirsiniz ve düzgün çalıştığını ama neden burada çıkarım çalışmaları yazın etmiyor? Elbette fonksiyon için genel tipler de belirtebilirim (her iki çözüm için aşağıya bakınız).

Ben Scala türlerini anlamak için söz konusu 'tarama' yürütülen ve beh2 görmek ve işlevi geçirilen ve Int olmak için burada U farz düşündük. Giriş parametrelerinin türlerini belirtmeden bunu düzeltmemin bir yolu var mı (kapanma veya jenerik için)?

DÜZENLEME: sahip iki düzeltmeler örnekler: Bu sorunu çözmek için yollar

beh.map1[Int, Int](beh2, (a, b) => a + b) 
beh.map1(beh2, (a, b : Int) => a + b) 

cevap

19

Burada neler olup bittiğine dair bir tartışma için bkz this scala-debate thread. Sorun, Scala'nın tür çıkarımının parametre listesi,parametresi parametresi başına gerçekleşmesidir.

Josh Suereth'in bu konuya dikkat ettiğinden, mevcut yaklaşımın iyi bir nedeni vardır. Scala, parametre başına tür çıkarımına sahipse, derleyici, aynı parametre listesindeki türler arasında bir üst sınır elde edemez. bizim istediğimiz gibi

trait X 
class Y extends X 
class Z extends X 

val y = new Y 
val z = new Z 

def f[A](a: A, b: A): (A, A) = (a, b) 
def g[A](a: A)(b: A): (A, A) = (a, b) 

f(y, z) tam çalışır, ancak g(y)(z) derleyici zaten A için türü olarak Y seçti İkinci argüman listesine vardığında beri, bir tür uyuşmazlığı verir: Aşağıdaki düşünün.

4

bir çok bağımsız değişken listesi tanımlamaktır.

def map1[U, V](behaviour: Behaviour[U])(func: (T, U) => V): Behaviour[V] = ... 

ve bu gibi kullanabilirsiniz: Yani map1 yöntemi şöyle tanımlanabilir olurdu

beh.map1(beh2)((a, b) => a + b) 
beh.map1(beh2)(_ + _) 

Ben tür kesmesi sizin durumda çalışmıyor neden tamamen emin değilim ama U tip parametresi kullanımı ile bir ilgisi olduğuna inanıyoruz. İlk ve ikinci argüman için iki kere kullanıyorsunuz. Derleyici bulmak için muhtemelen çok karmaşıktır. 2 argüman listesi durumunda, ilk argüman listesi derlemesi sırasında U çıkacak ve ikinci argüman listesi zaten çıkarılmış tip kullanacaktır.

+0

Çok teşekkürler, gayet iyi çalışıyor! Ertesi gün gerçekleşecek olan şey için bir açıklama yapamazsa cevabı kabul edeceğim. – seadowg

İlgili konular