简体   繁体   English

是否有必要在 class 声明的 class 上下文中指定每个超类?

[英]Is it necessary to specify every superclass in a class context of a class declaration?

The ArrowList class from the hxt package has the following declaration:来自ArrowList package 的 ArrowList class 具有以下声明:

class (Arrow a, ArrowPlus a, ArrowZero a, ArrowApply a) => ArrowList a where ... class (Arrow a, ArrowPlus a, ArrowZero a, ArrowApply a) => ArrowList a where ...

The ArrowPlus class is declared as: class ArrowZero a => ArrowPlus a where ... ArrowPlus class 声明为: class ArrowZero a => ArrowPlus a where ...

The ArrowZero class is declared as: class Arrow a => ArrowZero a where ... ArrowZero class 声明为: class Arrow a => ArrowZero a where ...

And the ArrowApply class is declared as: class Arrow a => ArrowApply a where ...并且ArrowApply class 被声明为: class Arrow a => ArrowApply a where ...

Why can't it just be written as: class (ArrowPlus a, ArrowApply a) => ArrowList a where ...?为什么不能直接写成: class (ArrowPlus a, ArrowApply a) => ArrowList a where ...?

No, it's not necessary to include all the superclasses.不,没有必要包含所有超类。 If you write如果你写

class (ArrowPlus a, ArrowApply a) => ArrowList a where

it will work.它会起作用的。 However, here are two possible reasons for mentioning all the superclasses explicitly.但是,这里有两个明确提及所有超类的可能原因。

  1. It might be more readable as you can tell at a glance what all the superclasses are.它可能更具可读性,因为您一眼就能看出所有超类是什么。

  2. It might be slightly more efficient, as listing the superclasses explicitly will result in a direct dictionary lookup at runtime, while for a transitive superclass it will first lookup the dictionary for the superclass and then lookup the class member in that.它可能会稍微高效一些,因为显式列出超类将导致在运行时直接查找字典,而对于传递超类,它将首先查找超类的字典,然后在其中查找 class 成员。

    For example, take this inheritance chain:例如,以这个 inheritance 链为例:

     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

    Looking at the generated core for this (with ghc -c -ddump-simpl ), we see that this generates a chain of lookup calls.查看为此生成的核心(使用ghc -c -ddump-simpl ),我们看到这会生成一个查找调用链。 It first looks up the dictionary for Baz in Xyzzy , then Bar in that, then Foo , and finally it can look up foo .它首先在Xyzzy中查找Baz的字典,然后在其中查找Bar ,然后是Foo ,最后它可以查找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)))

    Modifying the definition of Xyzzy to explicitly mention Foo :修改Xyzzy的定义以明确提及Foo

     class (Foo a, Baz a) => Xyzzy a

    We see that it can now get the Foo dictionary straight from the Xyzzy one and look up foo in that.我们看到它现在可以直接从Xyzzy字典中获取Foo字典并在其中查找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)

    Note that this may be GHC-specific.请注意,这可能是特定于 GHC 的。 Tested with version 7.0.2.使用版本 7.0.2 测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM