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

如何存储Either (Key a) (Key b)?Haskell共享实体多ID存储报错求助

解决Haskell中Sharing实体存储UserId/GroupId的类型作用域问题

你遇到的核心问题是类型不在当前作用域,不管是用Either还是自定义求和类型,本质都是UserId、GroupId或者你自定义的SharingIdType没被Haskell正确识别。我来一步步帮你解决:

1. 先确保基础类型UserId和GroupId已正确定义/导入

报错Not in scope: type constructor or class 'UserId'说明Haskell不知道UserId是什么类型。你需要先明确这个类型的定义:

如果是你自己定义的,要把它放在当前模块或者导入进来:

-- 示例:用newtype定义基础ID类型(也可以用data,根据你的需求调整)
newtype UserId = UserId Int
newtype GroupId = GroupId Int

如果UserId/GroupId是来自其他模块的,别忘了导入:

import YourModule (UserId, GroupId) -- 替换成实际的模块名

2. 正确定义并使用自定义求和类型SharingIdType

你尝试的自定义求和类型思路是完全正确的,报错Not in scope: type constructor or class 'SharingIdType'大概率是因为这个类型的定义位置不对,或者没被导入到使用它的地方。

正确的写法示例:

-- 先定义基础ID类型(确保它们在当前作用域内)
newtype UserId = UserId Int
newtype GroupId = GroupId Int

-- 定义你的求和类型,明确区分用户ID和群组ID
data SharingIdType = SharingUserId UserId | SharingGroupId GroupId

-- 现在定义Sharing实体,用SharingIdType来存储对象ID
data Sharing = Sharing
  { sharingObjectId :: SharingIdType
  -- 这里可以添加其他字段,比如sharingPermission、sharingCreatedAt等
  }

如果SharingIdType在另一个模块:

  • 在定义它的模块里要导出这个类型(包括构造函数,方便后续模式匹配):
    module YourDataModule
      ( UserId(..)
      , GroupId(..)
      , SharingIdType(..)
      , Sharing(..)
      ) where
    
    -- 然后是类型定义...
    
  • 在使用Sharing的模块里导入:
    import YourDataModule (SharingIdType(..), Sharing(..))
    

3. (可选)如果想用Either代替自定义类型

如果你觉得自定义类型麻烦,想用Either,只要确保UserId和GroupId在作用域,直接用就行:

data Sharing = Sharing
  { sharingObjectId :: Either UserId GroupId
  -- 其他字段...
  }

不过我更推荐自定义求和类型,因为Left/Right的语义不如SharingUserId/SharingGroupId清晰,后续模式匹配时可读性会高很多。

错误原因总结

所有Not in scope的类型错误,本质都是Haskell在当前代码的作用域里找不到对应的类型定义:

  • 要么是你没定义这个类型;
  • 要么是定义了但没导入到当前模块;
  • 要么是定义在局部作用域(比如某个函数内部),外部无法访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:11:37