将示例从 Haskell 翻译成 Scala(HKT,类型约束)
Translate a sample from Haskell to Scala (HKT, type constraints)
我正在学习函数式编程,我在 Haskell 中制作了这个示例,它按我想要的方式工作,但是当我不知道如何在 Scala 中进行此类约束时,我不明白我是如何做到的可以在 Scala atm 中使用 HKT 和约束。
{-# LANGUAGE GADTs #-}
module Complex
( Complex
, add
) where
data Complex a where
Complex :: (Show a, Fractional a) => a -> a -> Complex a
instance Show (Complex a) where
show (Complex a b) = "z = " ++ show a ++ " + i * " ++ show b
add :: Complex a -> Complex a -> Complex a
add (Complex a b) (Complex c d) = Complex (a + c) (b + d)
提前致谢:)
所以,我做到了,但似乎有点不对,我可以做得更好吗?
case class ComplexNumber[T](realPart: T, imagPart: T){
override def toString: String = s"z= $realPart + $imagPart i"
}
object ComplexNumber {
def add[T](a: ComplexNumber[T], b: ComplexNumber[T])(implicit evidence: Numeric[T]): ComplexNumber[T] = {
ComplexNumber(evidence.plus(a.realPart, b.realPart), evidence.plus(a.imagPart, b.imagPart))
}
}
我不得不使用这个证据助手似乎很奇怪..
希望这有帮助,但不能让对象泛型感到遗憾
case class Complex[T](real: T, img: T) {
override def toString: String = s"z= $real + $img i"
}
object Complex {
def add(cmplx: Complex[Double], cmplx2: Complex[Double]): Complex[Double]
= new Complex[Double](cmplx.real + cmplx2.real, cmplx.img + cmplx2.img)
}
val c1 = Complex[Double](3, 4)
val c2 = Complex[Double](5, 1)
println(Complex.add(c1, c2))
"evidence helper" 保证类型参数 T
仅限于可以加在一起(或任何其他算术运算)的数字类型。
它可以隐藏在一些语法糖后面,使 T
成为 "context bound" 类型参数。您还可以引入一些额外的隐式以使加法语法更自然。
object ComplexNumber {
import Numeric.Implicits._ //can be placed elsewhere in the file
def add[T: Numeric](a: ComplexNumber[T], b: ComplexNumber[T]):ComplexNumber[T] =
ComplexNumber(a.realPart + b.realPart, a.imagPart + b.imagPart)
}
您还可以使用更自然的客户端语法。
import Numeric.Implicits._
case class ComplexNumber[T: Numeric](realPart: T, imagPart: T){
override def toString: String = s"z= $realPart + $imagPart i"
def +(that: ComplexNumber[T]):ComplexNumber[T] =
ComplexNumber(this.realPart + that.realPart, this.imagPart + that.imagPart)
}
用法:
ComplexNumber(8,1) + ComplexNumber(4,4) //res0: ComplexNumber[Int] = z= 12 + 5 i
我正在学习函数式编程,我在 Haskell 中制作了这个示例,它按我想要的方式工作,但是当我不知道如何在 Scala 中进行此类约束时,我不明白我是如何做到的可以在 Scala atm 中使用 HKT 和约束。
{-# LANGUAGE GADTs #-}
module Complex
( Complex
, add
) where
data Complex a where
Complex :: (Show a, Fractional a) => a -> a -> Complex a
instance Show (Complex a) where
show (Complex a b) = "z = " ++ show a ++ " + i * " ++ show b
add :: Complex a -> Complex a -> Complex a
add (Complex a b) (Complex c d) = Complex (a + c) (b + d)
提前致谢:)
所以,我做到了,但似乎有点不对,我可以做得更好吗?
case class ComplexNumber[T](realPart: T, imagPart: T){
override def toString: String = s"z= $realPart + $imagPart i"
}
object ComplexNumber {
def add[T](a: ComplexNumber[T], b: ComplexNumber[T])(implicit evidence: Numeric[T]): ComplexNumber[T] = {
ComplexNumber(evidence.plus(a.realPart, b.realPart), evidence.plus(a.imagPart, b.imagPart))
}
}
我不得不使用这个证据助手似乎很奇怪..
希望这有帮助,但不能让对象泛型感到遗憾
case class Complex[T](real: T, img: T) {
override def toString: String = s"z= $real + $img i"
}
object Complex {
def add(cmplx: Complex[Double], cmplx2: Complex[Double]): Complex[Double]
= new Complex[Double](cmplx.real + cmplx2.real, cmplx.img + cmplx2.img)
}
val c1 = Complex[Double](3, 4)
val c2 = Complex[Double](5, 1)
println(Complex.add(c1, c2))
"evidence helper" 保证类型参数 T
仅限于可以加在一起(或任何其他算术运算)的数字类型。
它可以隐藏在一些语法糖后面,使 T
成为 "context bound" 类型参数。您还可以引入一些额外的隐式以使加法语法更自然。
object ComplexNumber {
import Numeric.Implicits._ //can be placed elsewhere in the file
def add[T: Numeric](a: ComplexNumber[T], b: ComplexNumber[T]):ComplexNumber[T] =
ComplexNumber(a.realPart + b.realPart, a.imagPart + b.imagPart)
}
您还可以使用更自然的客户端语法。
import Numeric.Implicits._
case class ComplexNumber[T: Numeric](realPart: T, imagPart: T){
override def toString: String = s"z= $realPart + $imagPart i"
def +(that: ComplexNumber[T]):ComplexNumber[T] =
ComplexNumber(this.realPart + that.realPart, this.imagPart + that.imagPart)
}
用法:
ComplexNumber(8,1) + ComplexNumber(4,4) //res0: ComplexNumber[Int] = z= 12 + 5 i