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

Haskell新手求教:如何实现中缀运算符<+合并两个手牌

解决Haskell自定义中缀运算符<+>的绑定错误

嘿,刚看到你的问题,这是个Haskell初学者很容易踩的小坑,我来帮你理清楚!

首先,你遇到的错误The type signature for ‘<+’ lacks an accompanying binding,核心原因是运算符的定义语法不对。Haskell里不能用h1 (<+) h2 = undefined这种写法来定义中缀运算符——编译器会误解这个写法,找不到和类型签名对应的函数实现绑定,所以才报了错。

正确的运算符实现方式

我们需要用两种标准语法之一来定义<+>,同时还要把undefined替换成实际的手牌合并逻辑:

方式1:前缀式定义(把运算符括起来作为函数名)

data Rank = Numeric Integer | Jack | Queen | King | Ace 
data Suit = Hearts | Spades | Diamonds | Clubs 
data Card = Card Rank Suit 
data Hand = Empty | Add Card Hand 

-- 类型签名保持不变
(<+) :: Hand -> Hand -> Hand
-- 用括号包裹运算符,以前缀函数的形式定义
(<+) Empty h2 = h2  -- 若第一个手牌为空,直接返回第二个手牌
(<+) (Add card h1Rest) h2 = Add card (h1Rest <+ h2)  -- 递归将h1的每张卡依次放在h2前方

方式2:中缀式定义(直接用运算符写等式)

这种写法更贴合中缀运算符的直观使用习惯:

data Rank = Numeric Integer | Jack | Queen | King | Ace 
data Suit = Hearts | Spades | Diamonds | Clubs 
data Card = Card Rank Suit 
data Hand = Empty | Add Card Hand 

(<+) :: Hand -> Hand -> Hand
Empty <+ h2 = h2  -- 空手牌与任何手牌合并,结果为对方
(Add card h1Rest) <+ h2 = Add card (h1Rest <+ h2)  -- 递归遍历h1,把每张卡前置到合并结果中

实现逻辑说明

这个递归定义的核心思路是:

  • 当第一个手牌h1为空(Empty),直接返回第二个手牌h2;
  • 当h1是Add card h1Rest(包含一张卡+剩余手牌),先保留当前的card,再递归合并h1Rest和h2,最后把card放在递归结果的最前面——这样就实现了把h1的所有卡置于h2上方的效果。

测试验证

你可以写个测试用例看看效果:

-- 创建两个测试手牌
testHand1 = Add (Card Ace Hearts) (Add (Card (Numeric 10) Spades) Empty)
testHand2 = Add (Card King Diamonds) Empty

-- 运行 testHand1 <+ testHand2 会得到:
-- Add (Card Ace Hearts) (Add (Card (Numeric 10) Spades) (Add (Card King Diamonds) Empty))

这样就完美实现了你想要的手牌合并功能啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:35:33