You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中如何重导出单个实体(如函数、数据构造器)

Haskell中如何重导出单个实体?

Haskell完全支持单个实体(函数、类型、构造器、类型类等)的重导出,不需要整体重导出整个模块。这个报错本质是对Haskell数据类型的导出规则不熟悉导致的。

你的代码中ReExport.hs实际导出的内容

你写的module ReExport ( SomeData ) where,仅导出了类型层面的类型构造器SomeData,没有导出同名的值构造器。
对于定义data SomeData = SomeData,实际上存在两个同名、分属不同层面的实体:

  • 类型层的SomeData:是一个类型名,仅能用于类型标注位置,比如val :: SomeData
  • 值层的SomeData:是无参值构造器,属于可在表达式中使用的 term 级实体,也就是写x = SomeData时想要调用的对象
    因为你只导出了类型层的SomeData,在值表达式里用它自然会触发*Illegal term-level use of the type constructor ‘SomeData’*错误。

单个实体重导出的正确写法

不同类型的实体,重导出写法略有区别:

  • 重导出普通函数、值、类型类
    直接在导出列表中写对应实体名即可。例如SomeData模块中定义了普通函数addOne,要单独重导出它只需要写:

    -- ReExport.hs
    module ReExport ( addOne ) where
    import SomeData
    

    导入ReExport的模块可以直接使用addOne,不会有任何问题。

  • 重导出数据类型及构造器

    • 仅导出类型构造器:直接写类型名,也就是你之前的写法SomeData,此时外部只能用这个名字做类型标注,不能用构造器创建值、做模式匹配
    • 导出类型+所有值构造器:在类型名后加(..),这是最常用的写法:
      module ReExport ( SomeData(..) ) where
      import SomeData
      
      修正后你的Main.hs里x = SomeData就能正常编译运行了。
    • 导出类型+指定部分值构造器:在括号里列需要导出的构造器名即可,比如SomeData(MkA, MkB)就只导出MkA、MkB两个构造器
    • 显式区分同名类型/值实体:如果需要明确指定导出某一层的实体,可以用type关键字标注类型层实体,pattern关键字标注值构造器/模式实体,写法如下:
      module ReExport ( type SomeData, pattern SomeData ) where
      import SomeData
      
      这种写法在存在命名冲突时可以精确控制导出内容,效果和SomeData(..)在单构造器场景下完全一致。

内容的提问来源于stack exchange,提问作者IzzDarki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:18:42