Есть ли в Scala сокращение для сокращения арности универсального типа? - PullRequest
11 голосов
/ 04 октября 2011

Я хочу вызвать метод Скалаза pure, чтобы поместить значение в монаду State. Следующие работы:

type IntState[A] = State[Int, A]
val a = "a".pure[IntState]
a(1)
    (Int, java.lang.String) = (1,a)

Я также могу исключить псевдоним типа (спасибо Scalaz's 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, *]]

Ответы [ 3 ]

6 голосов
/ 04 октября 2011

Для краткого применения частичного типа (arity-2) в Scala вы можете добавить обозначение типа следующим образом.

type ![F[_, _], X] = TF { type ![Y] = F[X,  Y] }

"a".pure[(State!Int)# !]

Обратите внимание, что мы можем добавить нотацию для двух конструкторов типа арности (или псевдонима типа).

6 голосов
/ 04 октября 2011

Не уверен, что это подходит как к лучшему, но вот один подход, который @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] = scalaz.States$$anon$1@1dc1d18

Вы можете сделать его немного лучше, используя псевдонимы символических типов.

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] = scalaz.States$$anon$1@1740235
1 голос
/ 20 сентября 2017

Самый популярный способ уменьшения арности - это добрый проектор (https://github.com/non/kind-projector) плагин, который также используется в библиотеке кошек. Включив этот плагин, ваш пример можно преобразовать в:

val a = "a".pure[State[Int, ?]]

Примечание: этот синтаксис будет включен в Dotty по умолчанию.

...