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

《炉石传说》建模代码中attackMM函数的类型不匹配问题

排查Haskell《炉石传说》建模代码中attackMM的类型错误

看起来你在attackMM函数里把Monad的使用逻辑和返回类型要求搞混了,这是触发大量类型不匹配错误的核心原因。咱们一步步拆解问题并修正:

核心问题分析

  1. 类型签名与内部操作不匹配:你的attackMM签名声明返回Board,但内部调用的findMinion1、findMinion2都返回Maybe Minion,damageMM返回Maybe (Minion, Minion)——这些都是Maybe Monad下的操作,整个do块的实际返回类型是Maybe Board,和签名要求的Board直接冲突。
  2. do块内的错误解构:你试图直接从damageMM的结果里取fst和snd,但damageMM返回的是Maybe (Minion, Minion),不能直接解构,得先在do块里提取完整元组。
  3. 普通值与Monad值的混用:killMinion返回的是普通Board,但在Maybe Monad的do块里,需要把它包装成Maybe Board才能保持流程统一。

修正后的attackMM函数

首先我们调整函数的类型签名,让它返回Maybe Board(这更符合Haskell的设计哲学,能明确表达"找不到随从则操作失败"的语义),然后修正do块逻辑:

attackMM :: Name -> Name -> Board -> Maybe Board
attackMM n m b = do
  m1 <- findMinion1 n b       -- 从己方战场查找目标随从,返回Maybe Minion
  m2 <- findMinion2 m b       -- 从对方战场查找目标随从,返回Maybe Minion
  (m1', m2') <- damageMM (Just m1) (Just m2)  -- 直接提取damageMM返回的受损随从元组
  let b1 = killMinion m1' b   -- 处理第一个随从的死亡判定
      b2 = killMinion m2' b1  -- 处理第二个随从的死亡判定
  return b2                   -- 将最终战场状态包装成Maybe返回

可选:强制返回Board的版本(不推荐)

如果你坚持要让attackMM返回Board(会丢失"操作失败"的信息),可以给一个默认值(比如原战场状态):

attackMM :: Name -> Name -> Board -> Board
attackMM n m b = case attackMMMaybe n m b of
  Just newBoard -> newBoard
  Nothing -> b
  where
    attackMMMaybe :: Name -> Name -> Board -> Maybe Board
    attackMMMaybe n m b = do
      m1 <- findMinion1 n b
      m2 <- findMinion2 m b
      (m1', m2') <- damageMM (Just m1) (Just m2)
      let b1 = killMinion m1' b
          b2 = killMinion m2' b1
      return b2

修正逻辑说明

  • 调整类型签名为Maybe Board,能准确反映函数的实际行为:找不到指定随从时返回Nothing,操作成功则返回Just Board。
  • 在do块里直接提取damageMM的元组,符合Maybe Monad的使用规则——只有当damageMM返回有效结果时,才会继续执行后续步骤。
  • 最后用return把普通Board包装成Maybe Board,让整个do块的返回类型保持统一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:07:27