pagina - ¿Por qué GHC Haskell no admite nombres de parámetros de registro sobrecargados?
haskell website (3)
La mejor manera que encontré, es usar un preprocesador para resolver este problema definitivamente bastante estúpido.
Haskell y GHC lo hacen fácil, porque todo el analizador de Haskell está disponible como una biblioteca normal. Puede simplemente analizar todos los archivos, hacer ese esquema de cambio de nombre (por ejemplo, «datos A {nombre :: Cadena}» y «deje a = A" Betty "en nombre a» en «datos A {a_Nombre :: Cadena}» y « deje a = A "Betty" en aNombre a ») dependiendo del tipo de datos a los que se aplica la función de nombre, usando el sistema de resolución de tipos, y escríbalos para compilarlos.
Pero honestamente, eso debería ser integrado en GHC. Tienes razón: es una tontería que esto no esté incluido.
De lo que estoy hablando es de que no es posible definir:
data A = A {name :: String}
data B = B {name :: String}
Sé que el GHC simplemente analiza estas funciones simples y la manera idiomática de resolver esto sería:
data A = A {aName :: String}
data B = B {bName :: String}
class Name a where
name :: a -> String
instance Name A where
name = aName
instance Name B where
name = bName
Después de haber escrito esto, no me gusta mucho ... ¿no podría esta clasificación de tipos formar parte del proceso de desugaring?
El pensamiento me vino cuando estaba escribiendo un análisis de Aeson JSON. Donde hubiera sido demasiado fácil simplemente derivar las instancias de FromJSON
para cada tipo de datos, tuve que escribir todo a mano (actualmente> 1k líneas y contando). Tener nombres como name
o simplemente value
en un registro de datos no es tan infrecuente.
http://www.haskell.org/haskellwiki/Performance/Overloading menciona que la sobrecarga de funciones introduce cierta sobrecarga en el tiempo de ejecución. Pero en realidad no veo por qué el compilador no podría resolver esto en tiempo de compilación y darles nombres diferentes internamente.
Esta pregunta de SO del 2012 indica más o menos razones históricas y apunta a un hilo de correo del 2006. ¿Ha cambiado algo recientemente?
Incluso si hubiera una sobrecarga en el tiempo de ejecución, a la mayoría de las personas no les importaría, ya que la mayoría del código difícilmente es crítico para el rendimiento.
¿Hay alguna extensión de lenguaje oculto que realmente permite esto? Otra vez no estoy seguro ... pero creo que Idris en realidad hace esto?
Muchas, en su mayoría menores razones. Uno es el problema planteado por una mejor respuesta , la sobrecarga solo en el primer argumento es insuficiente para manejar todos los casos útiles.
Usted podría "desugar"
data A { name :: String }
data B { name :: Text }
dentro
class Has''name a b | a -> b where
name :: a -> b
data A { aName :: String }
instance Has''name A String where
name :: aName
data B { bName :: Text }
instance Has''name B Text where
name :: bName
pero eso requeriría extensiones GHC (Dependencias funcionales) que aún no han llegado a la norma. Impediría usar solo ''nombre'' para la creación de registros, actualizaciones y coincidencia de patrones (los patrones de vista pueden ayudar allí), ya que ''nombre'' no es "solo" una función en esos casos. Probablemente puedas lograr algo muy similar con la plantilla Haskell.
Usando la sintaxis de registro
data A { name :: String }
define implícitamente una función
name :: A -> String
Si define tanto A
como B
con un { name :: String }
, tenemos definiciones de tipos en conflicto para el name
:
name :: A -> String
name :: B -> String
No está claro cómo funcionarían las clases de tipos implícitas propuestas porque si definimos dos tipos
data A { name :: String }
data B { name :: Text }
entonces acabamos de cambiar el problema a definiciones de clases de tipos conflictivas:
class Has''name a where
name :: a -> String
class Has''name a where
name :: a -> Text
En principio, esto podría resolverse de una forma u otra, pero esta es solo una de varias propiedades deseables y conflictivas difíciles para los registros. Cuando se definió Haskell, se decidió que era mejor tener un soporte simple aunque limitado en lugar de intentar diseñar algo más ambicioso y complicado. Se han discutido varias mejoras a los registros en varias ocasiones y hay discusiones perennes, por ejemplo, este hilo de Haskell Cafe . Tal vez algo se resolverá para Haskell Prime.