В Scala имеется ли сокращение для сокращения типичности типа?
Я хочу вызвать метод Scalaz pure
, чтобы поместить значение в государственную монаду. Следующие работы:
type IntState[A] = State[Int, A]
val a = "a".pure[IntState]
a(1)
(Int, java.lang.String) = (1,a)
Я также могу исключить псевдоним типа (спасибо Scalaz Pure.scala):
val a = "a".pure[({type T[A]=State[Int,A]})#T]
a(1)
(Int, java.lang.String) = (1,a)
Но это крайне неуклюже. Существует ли более короткий способ синтеза такого типа? Подобно синтаксису заполнителя для литералов функций, есть ли что-то вроде:
"a".pure[State[Int, *]]
Ответы
Ответ 1
Для краткого приложения с частичным типом (arity-2) в Scala вы можете вводить нотацию типа типа следующим образом.
type ![F[_, _], X] = TF { type ![Y] = F[X, Y] }
"a".pure[(State!Int)# !]
Обратите внимание, что мы можем вводить нотацию для двух конструкторов типа arity (или псевдонима типа).
Ответ 2
Не уверен, что это будет лучше, но вот один подход, который @kmizu написал в твиттере на другой день:
scala> trait TF {
| type Apply[A]
| }
defined trait TF
scala> type Curried2[F[_, _]] = TF {
| type Apply[X] = TF {
| type Apply[Y] = F[X, Y]
| }
| }
defined type alias Curried2
scala> "a".pure[Curried2[State]#Apply[Int]#Apply]
res7: scalaz.State[Int,java.lang.String] = [email protected]c1d18
Вы можете сделать это немного лучше, используя псевдонимы символического типа.
scala> type ![F[_, _]] = TF {
| type ![X] = TF {
| type ![Y] = F[X, Y]
| }
| }
defined type alias $bang
scala> "a".pure[![State]# ![Int]# !]
res9: scalaz.State[Int,java.lang.String] = [email protected]
Ответ 3
Самый популярный способ уменьшения arity - это kind-projector (https://github.com/non/kind-projector), который также используется в библиотеке кошек. Включив этот плагин, ваш пример можно преобразовать в:
val a = "a".pure[State[Int, ?]]
Примечание: этот синтаксис будет включен в Dotty по умолчанию.