16

En Haskell, los productos de tipo elevado significan que hay una diferencia semántica entre (a, b, c) y (a, (b, c)).¿Desventaja de los productos de tipo sin elevar?

Si todas las coincidencias de patrones de todos los productos fueran siempre irrefutables, entonces no habría diferencia, y (a, b, c) podría ser azúcar sintáctica para (a, (b, c)).

¿Por qué Haskell eligió levantar productos tipo?

+1

¿Porque una tupla aplanada es menos útil? – kennytm

+2

¿Por "aplanar" quiere decir sin elevación? Si es así, ¿por qué? No me parece obvio, y la tupla no levantada tiene mejores propiedades algebraicas formales. –

+1

Prefiero que sea azúcar sintáctica para '(a, (b, (c,())))' como HList – yairchu

Respuesta

6

Una de las razones es que la implementación de seq para un producto sin alzarse requiere computación paralela/intercalado, ya seq (a, b) True serían supone que es True si y sólo si al menos uno de a y b no es inferior. Es posible que no encuentre esta razón terriblemente convincente, dependiendo de cómo se siente acerca de seq, pero por supuesto polimórfica seq es por definición una parte de Haskell ...

+0

Creo que seq debería usar una clase de tipo, y creo que "seq" en su actual se debe permitir que la forma haga que un programa divergente termine, pero no al revés. – Peaker

+0

IOW, realmente no tengo un problema con seq (\ _ | \ _, \ _ | \ _) True == True incluso si las tuplas no se han subido. – Peaker

+0

En ese punto, es mejor no hacer '(a, b)' una instancia de 'Seq' (y lo mismo para' a -> b'). –

0

Puede producir una diferencia semántica si se quiere, en relación con el tipo de clases

(a, b, c) y (a, (b, c)) pueden crear instancias de clases de manera diferente. Sólo pienso en

show (1, 2, 3) 

y

show (1, (2, 3)) 

lo consideraría contrario a la intuición para tener tanto produciendo el mismo resultado.

+4

Realmente no me gusta esto. Provoca una explosión de N-tupla (p. Ej .: vea ": info Show" en ghci) y hace que sea imposible crear una instancia de just (a, b) para obtener instancias para todas las tuplas. Realmente no quiero tener semántica diferente para (a, b, c) que (a, (b, c)). Deseo mostrar para ambos acabo de regresar "(a, b, c)". Además, la incomposibilidad de las N-tuplas es realmente molesta. Necesitamos tener un millón de variantes de "fst" y "snd", Control.Arrow.first/second, accesadores de tupla de Data.Accessor, etc. – Peaker

8

¿Por qué Haskell decidió levantar los productos de tipo?

Puede justificar esta elección de diseño sin recurrir a la pereza o los patrones refutables. La misma elección de diseño se realiza ML por razones de soporte de polimorfismo. Consideremos

fst (x, y) = x 
snd (x, y) = y 

Ahora bien, si (a, (b, c)) es el azúcar sintáctica para (a, b, c), es muy difícil ver cómo se especializan fstsnd y para tomar este tipo de argumento. Pero

fst :: (a, (b, c)) -> a 
snd :: (a, (b, c)) -> (b, c) 

son perfectamente razonables. Debido a que las funciones polimórficas como fst y snd son tan increíblemente útiles, tanto Haskell como ML le dan al programador la capacidad de distinguir (a, (b, c)) y ((a, b), c) de (a, b, c).

(Para las personas que se preocupan por los costos, la estructura tipográfica también es una guía razonable para el tamaño del tipo y la cantidad de indirecciones (cargas) necesarias para obtener sus elementos. Algunos programadores necesitan o quieren saber sobre tales cosas y tener un pequeño grado de control sobre ellos.)

+3

Está respondiendo por qué (a, b, c) no es isomorfo a (a, (b, c)) (o, es más fácil trabajar con, (a, (b, (c,())))), pero no por qué los productos de tipo no se han subido. Levantar significa agregar un fondo, haciendo que (indefinido, indefinido) se distinga de indefinido. – luqui

+1

@luqui: De acuerdo. Elijo abordar la parte de la pregunta que se centra en la diferencia semántica entre '(a, (b, c))' y '(a, b, c)'. Cuando esa diferencia se enfoca, el levantamiento es obvio: las tuplas se levantan porque * todo * tipo se levanta. –

Cuestiones relacionadas