2017-04-12 19 views
6

Tôi đang cố gắng viết một hàm trung bình có trọng số chung. Tôi muốn thư giãn các yêu cầu về giá trị và trọng số của cùng một loại. tức là, tôi muốn hỗ trợ các chuỗi nói: (value:Float,weight:Int)(value:Int,weight:Float) đối số và không chỉ: (value:Int,weight:Int)Scala: generic function multiplying Numerics của các loại khác nhau

Để làm như vậy, trước tiên tôi cần triển khai hàm có hai giá trị số chung và trả về sản phẩm của chúng.

def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) : ??? = {...} 

Viết chữ ký và suy nghĩ về loại trả về, khiến tôi nhận ra rằng tôi cần xác định một số loại phân cấp cho Số để xác định loại trả về. tức là x:Float*y:Int=z:Float, x:Float*y:Double=z:Double.

Hiện tại, Lớp số xác định các hoạt động plus, times, v.v. chỉ cho các đối số cùng loại. Tôi nghĩ rằng tôi sẽ cần phải thực hiện một kiểu:

class NumericConverter[Numeirc[A],Numeric[B]]{ 
type BiggerType=??? 
} 

vì vậy mà tôi có thể viết lần chức năng của tôi như:

def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) : 
NumericConverter[Numeirc[A],Numeric[B]].BiggerType= {...} 

và chuyển đổi các "loại nhỏ" vào "một lớn hơn" và thức ăn nó đến times().

Tôi có đi đúng hướng không? Làm cách nào để "triển khai" BiggerType?

rõ ràng tôi không thể làm điều gì đó như:

type myType = if(...) Int else Float 

như được đánh giá tự động, vì vậy nó worn't làm việc.

Tôi hiểu rằng tôi có thể làm điều này Sử dụng Scalaz, v.v. nhưng đây là bài tập học thuật và tôi muốn hiểu cách viết một hàm trả về kiểu tĩnh dựa trên các loại đối số.

Hãy cho tôi biết nếu có cách nào dễ dàng hơn để thực hiện việc này.

cập nhật:

đây là những gì tôi đã đưa ra với nó.

abstract class NumericsConvert[A: Numeric,B: Numeric]{ 

    def AisBiggerThanB: Boolean 

    def timesA=new PartialFunction[(A,B), A] { 
     override def isDefinedAt(x: (A, B)): Boolean = AisBiggerThanB 
     override def apply(x: (A, B)): A = implicitly[Numeric[A]].times(x._1, x._2.asInstanceOf[A]) 
    } 

    def timesB=new PartialFunction[(A,B), B] { 
     override def isDefinedAt(x: (A, B)): Boolean = !AisBiggerThanB 
     override def apply(x: (A, B)): B = implicitly[Numeric[B]].times(x._1.asInstanceOf[B], x._2) 
    } 
    def times: PartialFunction[(A, B), Any] = timesA orElse timesB 
} 

def times[A: Numeric, B: Numeric](x: B, y: A)= implicitly[NumericsConvert[A,B]].times(x,y) 

đó là ngớ ngẩn như tôi sẽ phải tạo implicits cho cả

IntDouble extends NumericsConvert[Int,Double] 

DoubleInt extends NumericsConvert[Double,Int] 

chưa kể rằng kiểu trả về của times tại là Any, nhưng không phân biệt, Tôi nhận được lỗi cho các chức năng thời gian của tôi. Tôi nghĩ rằng tôi sẽ thêm nó ở đây trong trường hợp nó có thể giúp đỡ với đến một giải pháp. vì vậy câu hỏi phụ: làm thế nào tôi có thể vượt qua bối cảnh ràng buộc các loại của một lớp/chức năng khác như tôi đang cố gắng làm trong thời gian.

Trả lời

7

Tôi nghĩ rằng bạn đang thực hiện điều này khó khăn hơn mức cần thiết.

Bạn cần "bằng chứng" rằng cả hai tham số là Numeric. Với điều đó được thiết lập để cho bằng chứng thực hiện công việc. Scala sẽ sử dụng numeric widening để kết quả là tổng quát hơn của hai loại đã nhận.

def mult[T](a: T, b: T)(implicit ev:Numeric[T]): T = 
    ev.times(a,b) 

Nếu bạn muốn thu hút ít tiền hơn, bạn có thể rút ra những yêu cầu bắt buộc. Sau đó, nó dễ đọc và dễ hiểu hơn.

def mult[T: Numeric](a: T, b: T): T = { 
    import Numeric.Implicits._ 
    a * b 
} 

Proof:

mult(2.3f , 7) //res0: Float = 16.1 
mult(8, 2.1) //res1: Double = 16.8 
mult(3, 2)  //res2: Int = 6 

Để biết thêm về các loại thuốc chung và mở rộng số, this question, và câu trả lời của mình, có giá trị nghiên cứu.

+0

Duh! các diễn viên được thực hiện tại chỗ! : D – ShS

+0

vui lòng thêm tài liệu tham khảo vào http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#value-conversions trong câu trả lời của bạn để giải thích điều gì xảy ra phía sau hiện trường. – ShS

+0

Ok, vì vậy tôi đã có phương pháp của tôi làm việc, nhưng có một vấn đề nhỏ với nó. xem bạn có thể giúp tôi giải quyết nó không: http://stackoverflow.com/questions/43382282/scala-generic-weighted-average-function – ShS

Các vấn đề liên quan