¿Por qué no son equivalentes?
show $ if someCondition then someInt else some double
y
if someCondition then show someInt else show someDouble
Entiendo que si aísla la if ... else
parte en el primer ejemplo de una expresión en sí misma, entonces no puede representar su tipo con un tipo de suma anónima, el tipo de Int | Double
algo que podría hacer fácilmente en TypeScript (mencionando TypeScript porque es el tipo usé el idioma a menudo y eso admite los tipos de Suma), y tendría que recurrir al uso de los Either
datos que luego llamaría show
.
El ejemplo que di aquí es trivial, pero para mí tiene más sentido pensar "Ok, vamos a mostrar algo, y ese algo depende de someCondition
" en lugar de "Ok, si alguna condición es verdadera, entonces muestra algo, de lo contrario, muestra algo doble", y también permite para una menor duplicación de código (aquí el programa se repite dos veces, pero también podría ser una aplicación de función larga y, en lugar de una if ... else
, podría haber> 2 ramas para considerar)
En mi opinión, debería ser fácil para el compilador verificar si cada uno de los tipos que forman el tipo de suma (aquí Int | Double
) podría usarse como parámetro para show
funcionar y decide si los tipos son correctos o no. Aún mejor es que la show
función siempre devuelve un string
sin importar los tipos de parámetros, por lo que el compilador no tiene que llevar consigo todas las "ramas" posibles (por lo que todos los tipos posibles).
¿Es por elección que tal característica no existe? ¿O lo está implementando más difícil de lo que creo?
fuente
if ... then ... else ...
, debe tener el mismo tipo en la partethen
yelse
. Puede verlo como un operador ternario en algunos lenguajes de programación.making all conversions explicit
. En mi pregunta, no quiero que Haskell emitaInt
a unDouble
viceversa. Acabo de usar esos dos tipos como ejemplo. Podrías reemplazar cadaInt
cona
yDouble
conb
en mi pregunta de dónde derivan ambos tiposShow
. Entiendo que no hayanonymous sum types
en Haskell, pero me gustaría saber por qué ese es el caso y qué nos impide diseñar el lenguaje para tenerlo.x :: Int | Bool
y tenemos que compilarshow x
, no hay una manera fácil de saber qué puntero a función usar para llamarshow
, en un RTS basado en borrado de tipo. Probablemente necesitemos mantener información de nivel de tipo en tiempo de ejecución.(String, Int)
No es anónimo. Es solo un tipo de producto normal con una sintaxis divertida.(String | Int)
Sería muy diferente. Comience preguntándose si(Int|Int)
debería ser idénticoInt
y por qué.Respuestas:
Todas las partes de una expresión deben estar bien escritas. El tipo de
if someCondition then someInt else someDouble
tendría que ser algo asíexists a. Show a => a
, pero Haskell no admite ese tipo de cuantificación existencial.Actualización: como Chi señala en un comentario , esto también sería posible si Haskell tuviera soporte para los tipos de unión / intersección (que no son lo mismo que los tipos de suma / producto), pero desafortunadamente no.
fuente
Int ∪ Double
, entonces sabría que tiene uno de los dos, pero no podría establecer una coincidencia de patrones para ver cuál, por lo que solo podría hacer cosas que serían válidas para ambas posibilidades.typeof
operador que puede compensar la falta de etiquetado y ver qué tipo se utiliza de todos modos. Haskell está completamente borrado, por lo que si admitiera esta función, entonces no habría ningún equivalente a eso.Hay tipos de productos con sintaxis ligera, escrita
(,)
, en Haskell. Una cosa sería que un tipo de suma con una sintaxis ligera, algo así(Int | String)
, sería una gran idea. La realidad es mas complicada. Veamos por qué (me estoy tomando algunas libertadesNum
, no son importantes).Si esto debería devolver un valor de tipo como
(Int | String)
, ¿qué debería devolver el siguiente?(Int | Int)
obviamente, pero si esto es distinto de lo normal,Int
entonces estamos en serios problemas. Por(Int | Int)
lo tanto, debe ser idéntico a simpleInt
.Uno puede ver de inmediato que esto no es solo una sintaxis ligera para los tipos de suma, sino una característica de lenguaje completamente nueva. Un tipo diferente de sistema de tipos si se quiere. ¿Deberíamos tener uno?
Veamos esta función.
Ahora que tipo
mysteryType
tiene? Obviamente¿Correcto? ¿Qué pasa si
a
yb
son del mismo tipo?Esto debería ser claro
Int
como hemos acordado anteriormente. Ahora amysteryType
veces devuelve un tipo de suma anónima, y otras veces no, dependiendo de los argumentos que pase. ¿Cómo combinarías un patrón con esa expresión? ¿Qué demonios puedes hacer con él? Excepto cosas triviales como "show" (o cualquier método de otras clases de tipos de las que sería una instancia), no mucho. A menos que agregue información de tipo de tiempo de ejecución al idioma, es decir,typeof
está disponible, y eso hace que Haskell sea un idioma completamente diferente.Así que sí. ¿Por qué no es Haskell un TypeScript? Porque no necesitamos otro TypeScript. Si desea TypeScript, ya sabe dónde encontrarlo.
fuente