将样本从Haskell转换为Scala(HKT,类型约束)

时间:2018-01-11 13:56:44

标签: scala haskell type-constraints higher-kinded-types

我正在学习函数式编程,我在Haskell中做了这个样本它的工作方式与我想要的一样,但是当我不知道如何在Scala中做这样的约束时,我不明白我是怎么做的可以在Scala atm中使用HKT和Constraints。

{-# 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))
    }
  }

我必须使用这个证据助手似乎很奇怪。

2 个答案:

答案 0 :(得分:0)

希望这有所帮助,但不能让对象仿制药抱歉

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

答案 1 :(得分:0)

"证据助手"保证类型参数T仅限于可以一起添加的数字类型(或任何其他算术运算)。

它可以隐藏在一些语法糖背后,使T a"上下文绑定"类型参数。您还可以引入一些额外的含义,使添加语法更自然。

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