Vamos a hacer alguna inferencia. Recogemos un candidato del array, que es número. Recogemos otro candidato de isNeat, que es string o número. Ambos aparecen a un nivel de profundidad en la anidación, por lo que tienen la misma prioridad. Así que vamos a elegir el mejor supertipo común entre ellos. Eso es string o número. Así que ese es el valor que obtenemos.
Vemos que T es de tipo string o número, por lo que X es de tipo string o número. Parece correcto. Pero luego lo miras un poco, y te preguntas, espera un minuto, ¿qué hace string en X? No le dimos ningún string a find. IsNeat no puede producir strings, solo puede aceptar strings. Find en runtime no tiene forma de inspeccionar find y averiguar cuál es su tipo de argumento, por lo que no parece plausible que alguien que tiene un array de números de repente pueda producir un string de la nada, no tiene sentido. Si solo miras esto por un tiempo y te quedas mirando estos candidatos, como antes, no puedes simplemente mirar estos candidatos y averiguar qué hacer a menos que tengas alguna otra información.
La otra información que debes tener en cuenta aquí es si la T aparece en una posición covariante o contravariante, o podríamos hablar de esto en términos de entrada o posiciones de salida. Estos Ts del array están entrando en find y estos valores que estamos pasando a arg desde dentro de find están saliendo de find. Así que realmente necesitamos pensar en las posiciones de entrada y salida de los parámetros de tipo mientras los recogemos. Nuestro nuevo algoritmo es algo que solo puedo demostrar realmente con una función más complicada. He hecho que find tome dos arrays, y he hecho que isNeat también acepte Booleans. Pido disculpas por que sea un poco más largo, pero vamos a llamar a find, vamos a pasar un array de string o número en este primer array, un array de números en el segundo array, y luego nuestra función predicado en func aquí toma strings o números o Booleans. Hagamos una pequeña tabla, voy a condensar el ejemplo de código para que puedas verlo todo en pantalla a la vez.
Vamos a hacer alguna inferencia, vamos a recoger algunos candidatos. Voy a empezar en arg en realidad, así que vamos a alinear arg colon t a este valor de string o número Boolean, y eso nos va a dar nuestro candidato de entrada. Vamos a recoger de nuestro primer array t, que es un string o número, y nuestro dos nos da un array de números. Así que tenemos esta lista de candidatos aquí. Lo que parecemos querer elegir es string o número, así que lo que vamos a hacer para obtener ese resultado es que vamos a tratar las posiciones de entrada como un límite superior en el resultado, y luego vamos a hacer nuestro algoritmo de supertipo común mejor entre los otros candidatos de salida que tenemos. Así que nuestro mejor resultado es string o número, que está por debajo, en términos de Teoría de Tipos, de este límite superior de string o número o Boolean, y procederemos con la llamada como si hubieras llamado find o string o número. Eso significa que Boolean no aparece en X, lo cual es definitivamente el comportamiento correcto. Si modifico un poco este ejemplo, y digo que isNeat solo acepta números y luego paso un array de números y un array de strings, queremos emitir un error aquí, y idealmente el error que emitiríamos actuaría como si hubieras llamado isNeat de A e isNeat de B. Ese es el error en este programa, ¿verdad? Sabemos por la firma de find que es capaz de pasar un T de Array2 a func en la posición de arg, así que necesitamos emitir un error como si hubieras llamado isNeat de A, porque eso es lo que está pasando aquí, así que probemos nuestro algoritmo. Recogemos nuestro mejor candidato de salida de un string o un número en ese array, pero luego encontramos un límite superior de isNeat, porque vemos n colon número en una posición de entrada, y por lo tanto nos quedamos con número, como estamos infiriendo aquí.
Comments