Podría ser ligeramente más eficiente, ya que la lista de las superclases explícitamente dará lugar a una búsqueda de diccionario directa en tiempo de ejecución, mientras que para una superclase transitivos se sucederán las operaciones de búsqueda del diccionario para la superclase y luego buscar el miembro de la clase de ese.
Por ejemplo, tomar esta cadena de herencia:
module Example where
class Foo a where
foo :: a -> String
class Foo a => Bar a
class Bar a => Baz a
class Baz a => Xyzzy a
quux :: Xyzzy a => a -> String
quux = foo
Mirando el núcleo generado para este (con ghc -c -ddump-simpl
), vemos que esto genera una cadena de llamadas de búsqueda. Primero busca el diccionario para Baz
en Xyzzy
, luego Bar
en eso, luego Foo
, y finalmente puede buscar foo
.
Example.quux
:: forall a_abI. Example.Xyzzy a_abI => a_abI -> GHC.Base.String
[GblId, Arity=1, Caf=NoCafRefs]
Example.quux =
\ (@ a_acE) ($dXyzzy_acF :: Example.Xyzzy a_acE) ->
Example.foo
@ a_acE
(Example.$p1Bar
@ a_acE
(Example.$p1Baz @ a_acE (Example.$p1Xyzzy @ a_acE $dXyzzy_acF)))
La modificación de la definición de Xyzzy
mencionar explícitamente Foo
:
class (Foo a, Baz a) => Xyzzy a
Vemos que ahora puede obtener el diccionario Foo
directamente de la Xyzzy
uno y mirar hacia arriba en ese foo
.
Example.quux
:: forall a_abD. Example.Xyzzy a_abD => a_abD -> GHC.Base.String
[GblId, Arity=1, Caf=NoCafRefs]
Example.quux =
\ (@ a_acz) ($dXyzzy_acA :: Example.Xyzzy a_acz) ->
Example.foo @ a_acz (Example.$p1Xyzzy @ a_acz $dXyzzy_acA)
Tenga en cuenta que esto puede ser específico de GHC. Probado con la versión 7.0.2.
Esto es interesante ... Pensé que podría. – luqui
¿Por qué no probarlo? – fuz