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

Haskell导入模块后无法访问数据类型字段,提示‘Not in scope’求助

Haskell模块导出问题:无法访问数据类型字段

问题场景

我有一个名为Types.hs的Haskell文件,定义如下:

module Types
( KnapsackItem
) where

data KnapsackItem = KnapsackItem {
weight :: Int,
cost :: Int
} deriving (Show, Eq)

另有Main.hs文件(已简化):

import Types

evalTotal :: [KnapsackItem] -> [KnapsackItem] -> (Int, Int, String)
evalTotal items sub = (sum $ map weight sub, sum $ map cost sub, outputString)
    where outputString = "[" ++ unwords [if item `elem` sub then "1" else "0" | item 
    <- items] ++ "]"

main :: IO ()
main = do
    let items = [KnapsackItem {...}, KnapsackItem{...}, ...] -- 示例中省略细节
    print $ map (evalTotal items) (subsequences items)

运行时出现以下错误:

src/Main.hs:67:34: Not in scope: `weight'
src/Main.hs:67:56:
    Not in scope: `cost'
    Perhaps you meant one of these:
      `const' (imported from Prelude), `cos' (imported from Prelude),
      `cosh' (imported from Prelude)

可以看到我无法访问KnapsackItem的属性,但将数据定义移到Main.hs中并取消导入后就能正常运行。请问我哪里出错了?

问题原因与解决方法

问题出在Types模块的导出列表上。你只导出了KnapsackItem这个数据类型的名称,但没有导出它的字段访问器weight和cost——Haskell不会自动导出记录类型的字段,必须显式声明。

修改方案一:导出所有字段

修改Types.hs的导出列表,用(..)表示导出该数据类型的所有构造器和字段:

module Types
( KnapsackItem(..)
) where

data KnapsackItem = KnapsackItem {
weight :: Int,
cost :: Int
} deriving (Show, Eq)

修改方案二:显式指定导出字段

如果你只想导出特定字段,可以逐个列出:

module Types
( KnapsackItem(weight, cost)
) where

data KnapsackItem = KnapsackItem {
weight :: Int,
cost :: Int
} deriving (Show, Eq)

两种方式都能让Main.hs中的代码正常访问weight和cost字段,解决编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 07:57:46