¿Qué es un tipo de par superior en Scala?

Puede encontrar lo siguiente en la web:

  1. Tipo de mayor kinder tipo == constructor de tipo?

    class AClass[T]{...} // For example, class List[T] 

    Algunos dicen que se trata de un tipo de tipo kinded más alto, ya que abstrae sobre tipos que cumplirían con la definición.

    Los tipos de kinded más altos son tipos que toman otros tipos y construyen un nuevo tipo

    Aunque estos también son conocidos como constructor de tipo . (Por ejemplo, en Progtwigción en Scala ).

  2. Tipo de mayor kinder tipo == constructor de tipo que toma tipo constructor como un parámetro de tipo?

    En el documento Generics of a Higher Kind , puedes leer

    … tipos que resumen sobre tipos que resumen sobre tipos (‘tipos de alto grado’) … ”

    lo que sugiere que

     class XClass[M[T]]{...} // or trait YTrait[N[_]]{...} // eg trait Functor[F[_]] 

    es un tipo de mayor kinded.

Entonces, con esto en mente, es difícil distinguir entre el constructor de tipo , el tipo de mayor nivel y el constructor de tipo que toma los constructores de tipo como parámetro de tipo , por lo tanto, la pregunta anterior.

Permítanme compensar el comienzo de esta confusión al lanzarme con alguna desambiguación. Me gusta usar la analogía con el nivel de valor para explicar esto, ya que las personas tienden a estar más familiarizadas con él.

Un constructor de tipos es un tipo que puede aplicar para escribir argumentos para “construir” un tipo.

Un constructor de valor es un valor que puede aplicar a argumentos de valor para “construir” un valor.

Los constructores de valores generalmente se llaman “funciones” o “métodos”. También se dice que estos “constructores” son “polimórficos” (porque pueden usarse para construir “cosas” de “forma” variable) o “abstracciones” (ya que se abstraen sobre lo que varía entre las diferentes instancias polimórficas).

En el contexto de la abstracción / polymorphism, el primer orden se refiere al “uso único” de la abstracción: abstrae una vez sobre un tipo, pero ese tipo en sí no puede abstraerse sobre nada. Los generics de Java 5 son de primer orden.

La interpretación de primer orden de las caracterizaciones de abstracciones anteriores son:

Un constructor de tipo es un tipo que puede aplicar a los argumentos de tipo adecuados para “construir” un tipo apropiado.

Un constructor de valor es un valor que puede aplicar a los argumentos de valor adecuado para “construir” un valor adecuado.

Para enfatizar que no hay abstracción involucrada (supongo que se podría llamar a este “orden cero”, pero no lo he visto en ningún lugar), como el valor 1 o el tipo String , generalmente decimos que algo es un valor “apropiado” o tipo.

Un valor apropiado es “inmediatamente utilizable” en el sentido de que no está esperando argumentos (no se resume en ellos). Piense en ellos como valores que puede imprimir / inspeccionar fácilmente (¡serializar una función es hacer trampa!).

Un tipo apropiado es un tipo que clasifica los valores (incluidos los constructores de valores), los constructores de tipos no clasifican ningún valor (primero deben aplicarse a los argumentos de tipo correctos para obtener un tipo adecuado). Para instanciar un tipo, es necesario (pero no suficiente) que sea un tipo apropiado. (Puede ser una clase abstracta, o una clase a la que no tienes acceso).

“Higher-order” es simplemente un término genérico que significa el uso repetido de polymorphism / abstracción. Significa lo mismo para tipos y valores polimórficos. Concretamente, una abstracción de orden superior se abstrae de algo que se abstrae sobre algo. Para los tipos, el término “de mayor nivel” es una versión de propósito especial del “orden superior” más general.

Por lo tanto, la versión de orden superior de nuestra caracterización se convierte en:

Un constructor de tipos es un tipo que puede aplicar para escribir argumentos (tipos apropiados o constructores de tipos) para “construir” un tipo apropiado (constructor).

Un constructor de valor es un valor que puede aplicar a argumentos de valor (valores propios o constructores de valores) para “construir” un valor adecuado (constructor).

Por lo tanto, “orden superior” simplemente significa que cuando dices “abstraer sobre X”, ¡realmente lo dices en serio! La X que se abstrae no pierde sus propios “derechos de abstracción”: puede abstraer todo lo que quiera. (Por cierto, uso el verbo “abstracto” aquí para significar: omitir algo que no es esencial para la definición de un valor o tipo, de modo que pueda ser variado / proporcionado por el usuario de la abstracción como argumento .)

Aquí hay algunos ejemplos (inspirados en las preguntas de Lutz por correo electrónico) sobre los valores y tipos propios de primer orden y orden superior:

  proper first-order higher-order values 10 (x: Int) => x (f: (Int => Int)) => f(10) types (classes) String List Functor types String ({type λ[x] = x})#λ ({type λ[F[x]] = F[String]})#λ 

Donde las clases usadas fueron definidas como:

 class String class List[T] class Functor[F[_]] 

Para evitar el direccionamiento indirecto mediante la definición de clases, debe express de alguna manera funciones de tipo anónimas, que no se pueden express directamente en Scala, pero puede usar tipos estructurales sin demasiada carga sintáctica (el estilo se debe a https: // stackoverflow .com / users / 160378 / retronym afaik):

En alguna versión futura hipotética de Scala que admita funciones de tipo anónimas, podría acortar esa última línea de los ejemplos a:

 types (informally) String [x] => x [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be 

(En una nota personal, lamento haber hablado sobre “tipos de mayor nivel”, ¡son solo tipos después de todo! Cuando absolutamente necesitas desambiguar, te sugiero que digas cosas como “tipo parámetro constructor”, “tipo miembro constructor” , o “tipo constructor alias”, para enfatizar que no se trata solo de los tipos adecuados).

PD: Para complicar aún más las cosas, “polimórfico” es ambiguo de una manera diferente, ya que un tipo polimórfico a veces significa un tipo universalmente cuantificado, como Forall T, T => T , que es un tipo apropiado, ya que clasifica los valores polimórficos ( en Scala, este valor puede escribirse como el tipo estructural {def apply[T](x: T): T = x} )

(Esta respuesta es un bash de decorar la respuesta de Adriaan Moors por información gráfica e histórica).

Los tipos de mayor nivel son parte de Scala desde 2.5.

  • Antes, Scala, como Java hasta ahora, no permitía usar type constructor (“generics” en Java) para usar como parámetro de tipo en un constructor de tipos. p.ej

      trait Monad [M[_]] 

    no fue posible

    En Scala 2.5, el sistema de tipos se ha ampliado por la capacidad de clasificar tipos en un nivel superior (conocido como polymorphism constructor de tipos ). Estas clasificaciones se conocen como tipos.

    Tipo y realce tipo, ** derivado ** de (Imagen derivada de Generics of a Kind Higher )

    La consecuencia es que ese constructor de tipo (por ejemplo, List ) podría usarse como otros tipos en la posición de parámetro de tipo de los constructores de tipo y por lo tanto se convirtieron en tipos de primera clase desde Scala 2.5. (Similar a las funciones que son valores de primera clase en Scala).

    En el contexto de un tipo de sistema que admite tipos superiores, podemos distinguir tipos apropiados , tipos como Int o List[Int] de tipos de primer orden como List y tipos de un tipo superior como Functor o Monad (tipos que resumen sobre tipos que resumen sobre tipos).

    El sistema de tipos de Java del otro lado no admite tipos y, por lo tanto, no tiene ningún tipo de “clase superior”.

    Entonces esto tiene que verse en el contexto del sistema de tipos de soporte.

  • En el caso de Scala, a menudo se ven ejemplos de un tipo constructor como

      trait Iterable[A, Container[_]] 

    con el título “Tipos de mayor calidad”, por ejemplo, en Scala para progtwigdores generics, sección 4.3

    Esto a veces es engañoso, porque muchos se refieren a Container como un tipo de mayor kinded y no Iterable , pero lo que es más preciso es,

    el uso de Container como parámetro de constructor de tipo de un tipo más alto de kinded (orden superior) aquí Iterable .

El tipo de tipos comunes como Int y Char , cuyas instancias son valores, es * . El tipo de constructores de tipo unario como Maybe es * -> * ; constructores tipo binarios como Either tienen ( curried ) tipo * -> * -> * , y así sucesivamente. Puede ver tipos como Maybe y Either como funciones de nivel de tipo: toman uno o más tipos y devuelven un tipo.

Una función es de orden superior si tiene un orden mayor que 1, donde el orden es (informalmente) la profundidad de anidamiento, a la izquierda, de las flechas de función:

  • Ordene 0: 1 :: Int
  • Orden 1: chr :: Int -> Char
  • Orden 2: fix :: (a -> a) -> a , map :: (a -> b) -> [a] -> [b]
  • Orden 3: ((A -> B) -> C) -> D
  • Orden 4: (((A -> B) -> C) -> D) -> E

Así que, para abreviar, un tipo de mayor nivel es solo una función de orden superior de nivel de tipo.

  • Orden 0: Int :: *
  • Orden 1: Maybe :: * -> *
  • Orden 2: Functor :: (* -> *) -> Constraint -higher-kinded: convierte los constructores de tipo unario en restricciones de clase de tipo

Yo diría: Un tipo de tipo más alto abstrae sobre un constructor de tipo. Por ejemplo, considere

 trait Functor [F[_]] { def map[A,B] (fn: A=>B)(fa: F[A]): F[B] } 

Aquí Functor es un “tipo de mayor nivel de formación” (como se usa en el documento “Genéricos de una clase superior”). No es un constructor de tipo concreto (“primer orden”) como List (que se abstrae únicamente de los tipos adecuados). Resume todos los constructores de tipo unarios (“primer orden”) (como se indica con F[_] ).

O para decirlo de otra manera: en Java, tenemos claramente constructores de tipo (por ejemplo, List ), pero no tenemos “tipos de kinded superiores”, porque no podemos abstraerlos (por ejemplo, no podemos escribir el Interfaz de Functor definida anteriormente, al menos no directamente ).

El término “polymorphism de orden superior (constructor de tipo)” se utiliza para describir sistemas que admiten “tipos de tipo superior”.