Введите параметр для обеспечения реляционных операторов - PullRequest
2 голосов
/ 31 марта 2020

Я пытался определить, как можно написать параметр типа, который ограничивает функцию типами, поддерживающими реляционные операторы?

Например:

def biggerOf[A <: ???](a: A, b: A): A = { if (a > b) a else b }

Где ??? моя дилемма. Расширенные биты параметров типа являются новыми для меня, поэтому просим немного помочь. Мысль AnyVal может быть победителем, но для типа Юнит (и логическое значение, которое не сломается, но не будет работать). Спасибо за любые идеи.

Ответы [ 3 ]

5 голосов
/ 31 марта 2020

Вы хотите задействовать класс типов Ordering.

import scala.math.Ordering.Implicits.infixOrderingOps

def biggerOf[A:Ordering](a: A, b: A): A = { if (a > b) a else b }

A:Ordering ограничивает A типами в классе типов Ordering, а infixOrderingOps включает вспомогательные операторы (методы) такие как <, >=, et c.

3 голосов
/ 31 марта 2020

Вы можете использовать заказ класс типов .

def biggerOf[A : Ordering](a: A, b: A): A = {
  import Ordering.Implicits._
  if (a > b) a else b
}
0 голосов
/ 31 марта 2020

Как предположили Луис и jwvh, вы можете использовать класс типов Ordering, но я хотел бы представить вам шаблон классов типов и использовать классы типов для ограничения более глубокого использования функции.

Класс типов позволяет быть гибким в своих родовых типах c, ограничивая его настолько, чтобы те, у кого нет экземпляра класса типов, не могли использовать вашу функцию.

Возьмите это в качестве примера, предполагая, что числовые типы данных в Scala не имеют операторов, мы можем обобщить идею работы с ними, введя класс типов Num, а затем указав их поведение в операции, поскольку эти числовые типы данных имеют разные способы обработки алгебраических операций c. (например, Integral против действительного числа)

trait Num[A] {

  def add(l: A, r: A): A
  def sub(l: A, r: A): A
  def mul(l: A, r: A): A
  def div(l: A, r: A): A

}

object NumTest {
  def addThenMultiply[A](l: A, r: A)(implicit ev: Num[A]): A =
    ev.mul(ev.add(l, r), r)

  //then we create Num instances for numerical types

  implicit val intNum = new Num[Int] { /* implementation*/ }
  implicit val floatNum = new Num[Float] { /* implementation */ }
}

Теперь в этом случае функция addThenMultiply будет работать только для типов данных Int и Float, поскольку они являются единственными, которые имеют Num экземпляр, но вы можете добавить экземпляры для других пользовательских типов данных также в зависимости от ваших потребностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...