我知道..
可以用于范围,即[1..3] == [1,2,3]
,而[10..]
是从10开始的无限列表。
然而,最近我也开始在括号内看到这些双点。作为(..)
或{..}
。
例如,import语句可以读取import Colog (HasLog (..))
我的第一直觉是认为这意味着HasLog有几个组件,我们正在显式地导入所有组件。但是,这与简单地导入HasLog(没有(..)
(有何不同?
此外,(..)
与{..}
有何不同?
(..)
和{..}
都是将与数据类型相关的名称引入作用域的方法,但它们非常不同,在不同的上下文中使用。
-
(..)
语法专门用于import
和导出列表。这是用于声明要导入/导出的数据类型的构造函数和/或记录字段的语法的一部分。例如,如果我有一个模块module FooM where data Foo = F0 | F1 | F2 data Bar = Bar { b0 :: Int, b1 :: Char }
然后编译
import FooM ( Foo(F1,F2), Bar(b1) ) fu = F1 ba = b1
但这不是
import FooM ( Foo(F1,F2) ) fu = F0
因为我只导入了
F1
和F2
构造函数,而没有导入F0
。如果我写import FooM ( Foo(..), Bar(..) ) fu = F0 ba = b0
它也起作用,因为它导入所有构造函数和记录标签。相比之下,使用
import FooM ( Foo ) fu = F0
您根本不导入任何构造函数或记录字段,只导入
Foo
作为不透明类型,因此这里fu = F0
也不会编译。(如果您希望数据类型的内部结构是"私有"的,并且只能通过实用程序函数、智能构造函数等进行操作,则在导出列表中经常会利用这一点。( -
CCD_ 19是CCD_ 20扩展的一部分。简而言之,它将应用于参数的所有记录标签的名称转换为本地范围的变量
我建议不要使用它,它是试图解决Haskell记录系统缺点的扩展之一,而IMO并没有取得多大成功。最好以传统方式使用记录,或者自动生成一些镜头并使用这些镜头来完全避免记录问题。