括号内的双点在Haskell中是什么意思



我知道..可以用于范围,即[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
    

    因为我只导入了F1F2构造函数,而没有导入F0。如果我写

    import FooM ( Foo(..), Bar(..) )
    fu = F0
    ba = b0
    

    它也起作用,因为它导入所有构造函数和记录标签。相比之下,使用

    import FooM ( Foo )
    fu = F0
    

    您根本不导入任何构造函数或记录字段,只导入Foo作为不透明类型,因此这里fu = F0也不会编译。(如果您希望数据类型的内部结构是"私有"的,并且只能通过实用程序函数、智能构造函数等进行操作,则在导出列表中经常会利用这一点。(

  • CCD_ 19是CCD_ 20扩展的一部分。简而言之,它将应用于参数的所有记录标签的名称转换为本地范围的变量
    我建议不要使用它,它是试图解决Haskell记录系统缺点的扩展之一,而IMO并没有取得多大成功。最好以传统方式使用记录,或者自动生成一些镜头并使用这些镜头来完全避免记录问题。

相关内容

  • 没有找到相关文章

最新更新