¿Cuál es la suposición hecha en "Learn You a Haskell" al deducir el tipo?

18

Esta pregunta no es subjetiva. Se utiliza un verbo muy específico en el libro de referencia, y me gustaría entender cuál es la implicación de esa redacción, porque me temo que estoy malinterpretando algo.

De Learn You a Haskell , el siguiente párrafo es el tercero y último que contiene "asumimos *".

data Barry t k p = Barry { yabba :: p, dabba :: t k }  

Y ahora queremos que sea una instancia de Functor. Functorquiere tipos de tipos, * -> *pero Barryno parece que tenga ese tipo. ¿Cuál es el tipo de Barry? Bueno, vemos que toma tres parámetros de tipo, por lo que será something -> something -> something -> *. Es seguro decir que pes un tipo concreto y, por lo tanto, tiene una especie de *. Para k, suponemos *y así, por extensión, ttiene una especie de* -> * . Ahora vamos a reemplazar esos tipos con los somethings que usamos como marcadores de posición y vemos que tiene una especie de (* -> *) -> * -> * -> *.

¿Por qué estamos asumiendo algo? Al leer "asumimos X (es decir, suponemos que X es verdadero)" es natural para mí pensar que también deberíamos considerar el caso de que X es falso. En el caso específico del ejemplo, ¿no podría tser amable (* -> *) -> *y kamable (* -> *)? Si este fuera el caso, lo que sea ty krealmente fuera, t kseguiría siendo un tipo concreto, ¿no?

Veo que toda la línea de razonamiento se compara con el compilador, pero no creo que el compilador asuma . Si es así, me gustaría saber qué, si no es así, nuevamente me temo que me estoy perdiendo el significado del párrafo.

Enrico Maria De Angelis
fuente
44
Estás en lo correcto. De hecho, podemos tener k :: Lpara cualquier tipo L, siempre y cuando t :: L -> *. Sin embargo, un compilador aquí debe elegir algunos específicos L, o recurrir a un polykind. Un polykind sería la opción más general, pero aquí elige GHC L = *(Haskell básico no tiene polykinds, deben activarse como una extensión). Como elige algo que es bastante arbitrario, LYAH usa la palabra "asumir" (AFAICT).
chi
1
Ok, tal vez el compilador asume que me habría desconcertado al menos menos de lo que suponemos , o no lo habría hecho .
Enrico Maria De Angelis

Respuestas:

19

De hecho, ¡el compilador asume! Pero puede pedir que no lo haga con la extensión PolyKinds. Puedes leer sobre esto con más detalle aquí . Con esa extensión activada, el tipo de Barryserá forall k. (k -> *) -> k -> * -> *.

Daniel Wagner
fuente
-1

Buen punto. El autor hace una suposición innecesaria. Quizás solo para que sea más fácil de entender en su capítulo de Type Foo, pero las personas como usted pueden cuestionar esto con razón.

Ambas t, ky pson variables de tipo. Como vemos yabba :: p, puede vivir solo, por lo que es como una función constante, como si fuera un valor en lugar de un tipo, su firma de tipo diría Into Char, lo que sea ... lo que sea. Pero dado que es un tipo, su firma es amable *.

Sin embargo tescriba aquí tiene una variable de tipo kpara la construcción de un tipo ( dabba :: t k) por lo que estamos seguros de que (sin assumtion aquí) ttiene una firma misma clase * -> *y ktiene* .

Una vez que sabemos esto ... el tipo Barry t k p's firma tipo es (* -> *) -> * -> * -> *lo que significa que se necesita ta continuación, ky luego py nos da Barryescribe.

Editar Asegúrese de leer el comentario de @ luqui a continuación.

Redu
fuente
77
kno está obligado a ser *como usted afirma que es mientras deduce t. Podríamos tener k :: * -> *y t :: (* -> *) -> *, por ejemplo. Agregue un campo doo :: k Intal registro y pasará sin problemas.
luqui
@luqui ... Sí, tienes razón ... No borraré esta respuesta ya que tu comentario realmente vale la pena.
Reducido