type class NumberLike

问题描述 投票:0回答:1

我想引入一个具有比较编号的类型类,例如类型,但还要有日期。

这是我的类型类别:

trait NumberLike[A] {
  def lessThenOrEqual[B](a: A, b: B): Boolean
  def moreThenOrEqual[B](a: A, b: B): Boolean
}

object NumberLike {
  def apply[A](implicit numericalLike: NumberLike[A]): NumberLike[A] =
    numericalLike

  def lessThenOrEqual[A: NumberLike, B](a: A)(b: B): Boolean =
    NumberLike[A].lessThenOrEqual(a, b)
  def moreThenOrEqual[A: NumberLike, B](a: A)(b: B): Boolean =
    NumberLike[A].moreThenOrEqual(a, b)

  def instance[A, B](
      lTOE: (A, B) => Boolean,
      mTOE: (A, B) => Boolean
  ): NumberLike[A] = new NumberLike[A] {
    def lessThenOrEqual[B](a: A, b: B): Boolean = lTOE(a, b)
    def moreThenOrEqual[B](a: A, b: B): Boolean = mTOE(a, b)
  }

  implicit class NumericalLikeOps[A: NumberLike](a: A) {
    def lessThenOrEqual[B](b: B): Boolean = NumberLike[A].lessThenOrEqual(a, b)
    def moreThenOrEqual[B](b: B): Boolean = NumberLike[A].moreThenOrEqual(a, b)
  }
}

问题是我想让函数lessThenOrEqual(a,b)可以放入另一种类型,因为我将比较整数和浮点数。但是,如果我可以比较的话,每种类型的类型类将只是一个,例如,如果一个类型具有多个其他类型的整数,可以说整数和浮点数。因此,类型B仅是功能说明,而不应该是类型类的变量。

对于实例,我将遇到类型B不被接受为函数变量的问题。

是否有任何解决方法?或者换句话说,如何在实例定义中使变量B只是针对lTOE的特定功能?

scala types functional-programming typeclass
1个回答
0
投票

听起来像您具有多参数类型类。

trait NumberLike[A, B] {
  def lessThenOrEqual(a: A, b: B): Boolean
  def moreThenOrEqual(a: A, b: B): Boolean
}

object NumberLike {
  def apply[A, B](implicit numericalLike: NumberLike[A, B]): NumberLike[A, B] =
    numericalLike

  def lessThenOrEqual[A, B](a: A)(b: B)(implicit nl: NumberLike[A, B]): Boolean =
    NumberLike[A, B].lessThenOrEqual(a, b)
  def moreThenOrEqual[A, B](a: A)(b: B)(implicit nl: NumberLike[A, B]): Boolean =
    NumberLike[A, B].moreThenOrEqual(a, b)

  def instance[A, B](
                     lTOE: (A, B) => Boolean,
                     mTOE: (A, B) => Boolean
                    ): NumberLike[A, B] = new NumberLike[A, B] {
    def lessThenOrEqual(a: A, b: B): Boolean = lTOE(a, b)
    def moreThenOrEqual(a: A, b: B): Boolean = mTOE(a, b)
  }

  object ops {
    implicit class NumericalLikeOps[A, B](a: A)(implicit numericalLike: NumberLike[A, B]) {
      def lessThenOrEqual(b: B): Boolean = NumberLike[A, B].lessThenOrEqual(a, b)
      def moreThenOrEqual(b: B): Boolean = NumberLike[A, B].moreThenOrEqual(a, b)
    }
  }

  implicit val intFloatNumberLike: NumberLike[Int, Float] = instance(_ <= _, _ >= _)
}

import NumberLike.ops._
1 lessThenOrEqual 2.0f
© www.soinside.com 2019 - 2024. All rights reserved.