记录类型默认相等性?PureScript地址查询函数Eq实例缺失报错求助
解决
findByAddress的Eq实例错误 & 记录类型相等性说明 先解决你的报错问题
你遇到的No type class instance was found for Data.Eq.Eq { street :: String , city :: String , state :: String }错误,核心原因是:PureScript不会自动为自定义记录类型生成Eq类型类实例。==运算符的使用依赖于Eq实例,当你尝试比较两个地址记录时,编译器找不到对应的实例就会抛出这个错误。
这里有两种简洁的解决方式:
1. 派生Eq实例(推荐)
如果你的地址是一个命名类型(比如你可能定义了type Address = { street :: String, city :: String, state :: String }),直接添加派生实例即可:
-- 先定义你的地址类型(如果还没定义的话) type Address = { street :: String, city :: String, state :: String } -- 派生Eq实例,编译器会自动基于字段的Eq实现生成记录的相等逻辑 derive instance eqAddress :: Eq Address
如果是用newtype包装的地址类型,同样可以派生:
newtype Address = Address { street :: String, city :: String, state :: String } derive instance eqAddress :: Eq Address
2. 手动实现Eq实例(自定义逻辑时用)
如果你需要自定义地址的相等规则(比如忽略大小写),可以手动写实例:
instance eqAddress :: Eq Address where eq a b = a.street == b.street && a.city == b.city && a.state == b.state
修改完实例后,你的findByAddress函数就能正常工作了,建议给函数加上明确的类型签名(帮助编译器推导,也让代码更清晰):
findByAddress :: Address -> Array Entry -> Maybe Entry findByAddress address = head <<< filter filterEntry where filterEntry :: Entry -> Boolean filterEntry entry = entry.address == address
关于记录类型的默认相等性
PureScript里的记录类型没有默认的相等比较行为,这和很多语言的默认对象比较不同。要让记录支持==,必须满足两个条件:
- 记录的所有字段类型都已经实现了
Eq实例(比如String、Int这些基础类型自带Eq) - 为这个记录类型显式定义或派生
Eq实例
当你通过derive生成Eq实例时,编译器会生成逐字段的浅比较逻辑——只有当两个记录的所有对应字段都相等时,它们才会被判定为相等,这是日常开发中最常用的规则。
PSCi测试示例
在PSCi里加载你的模块后,可以这样测试:
> import YourModuleName > let sampleEntry = { address: { street: "5th Ave", city: "New York", state: "NY" }, name: "Jonah" } -- 假设Entry有name字段 > findByAddress { street: "5th Ave", city: "New York", state: "NY" } [sampleEntry] Just { address: { street: "5th Ave", city: "New York", state: "NY" }, name: "Jonah" } > findByAddress { street: "Fake St", city: "Boston", state: "MA" } [sampleEntry] Nothing
内容的提问来源于stack exchange,提问作者Jonah
相关产品推荐
相关产品推荐

