Как использовать псевдоним типа для определения конструктора типа - PullRequest
5 голосов
/ 08 октября 2019

Допустим, у меня есть некоторый код, который использует List

def processList(input: List[Int]): List[Int]

Я хочу заменить список другими типами коллекций, такими как Vector.

Есть ли способ определить конструктор типа такчто я могу написать что-то вроде

type SomeCollection[_] = List[_]

def processList(input: SomeCollection[Int]): SomeCollection[Int]

Теперь я написал processList в терминах SomeCollection. Чтобы изменить SomeCollection на Vector, я просто изменяю псевдоним типа, и везде в кодовой базе, где я использую SomeCollection, я теперь использую Vector. Вот так:

type SomeCollection[_] = Vector[_]

def processList(input: SomeCollection[Int]): SomeCollection[Int]

Таким образом, мне нужно менять кодовую базу только в одном месте, а не везде.

Я не хочу писать

type SomeIntCollection = List[Int]

потому что я подключил коллекцию к типу Int.

Есть ли способ?

1 Ответ

7 голосов
/ 08 октября 2019

Вы довольно близки, это можно сделать в духе

type SomeCollection[A] = List[A]

def processList(input: SomeCollection[Int]): SomeCollection[Int] = input.map(_+1)

Однако, есть лучшие способы описать абстракцию. В библиотеке cats есть множество классов типов, предназначенных для абстрагирования по типу операции, которую вы хотите выполнить. Вышеуказанное с кошками выглядело бы примерно так:

import cats._
import cats.implicits._

def process[F[_]: Functor](input: F[Int]): F[Int] = input.map(_+1)

Это не привязывает вас к определенной базовой коллекции, так что вы можете свободно использовать все, что имеет смысл на сайте вызовов.

...