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

如何修正Haskell蛋糕烘焙状态机的语法错误与逻辑问题?

蛋糕烘焙状态机Haskell实现修正问题

需求说明

已定义如下Haskell类型:

data Event = AddEggs | AddFlour | AddSugar | Mix | Bake
  deriving (Eq, Show)
data State = Start | Error | Finished | HasEggs | HasFlour | HasSugar | HasFlourAndSugar | Mixed 
  deriving (Eq, Show)

状态机规则:

  • 初始状态为Start,终止状态为Error或Finished
  • 合法事件序列:
    1. [AddEggs, AddFlour, AddSugar, Mix, Bake]
    2. [AddEggs, AddSugar, AddFlour, Mix, Bake]
  • AddFlour与AddSugar顺序可互换
  • 进入Error或Finished后状态不再变更
  • 任何违规操作直接进入Error且无法恢复

原始实现代码

data Event = AddEggs | AddFlour | AddSugar | Mix | Bake
  deriving (Eq, Show)

data State = Start | Error | Finished | HasEggs | HasFlour | HasSugar | HasFlourAndSugar | Mixed 
  deriving (Eq, Show)

stepHelper :: State -> Event -> Bool -> Bool -> State

stepHelper Start AddEggs False False = HasEggs
stepHelper Start AddEggs True _ = Error
stepHelper Start AddEggs _ True = Error
stepHelper Start _ _ _ = Error

stepHelper HasEggs AddFlour has_flour has_sugar = if has_flour then Error else HasFlour
stepHelper HasEggs AddSugar has_flour has_sugar = if has_sugar then Error else HasSugar

stepHelper HasEggs AddFlour _ has_sugar = stepHelper HasEggs AddFlour True has_sugar
stepHelper HasEggs AddSugar has_flour _ = stepHelper HasEggs AddSugar has_flour True
stepHelper _ Mix has_flour has_sugar = if has_flour && has_sugar then Mixed else Error
stepHelper Mixed Bake _ _ = Finished

step :: State -> Event -> State
step s e = stepHelper s e False False

-- do not edit this
bake :: [Event] -> State
bake events = go Start events
  where go state [] = state
        go state (e:es) = go (step state e) es

报错信息

运行stack runhaskell Set7Test.hs后出现:

Set7.hs:61:1: warning: [-Wtabs]
    Tab character found here, and in 29 further locations.
    Please use spaces instead.
   |
61 |         ------------------------------------------------------------------------------
   | ^^^^^^^^

Set7.hs:119:29: error: parse error on input `='
    |
119 |             go state (e:es) = go (step state e) es

修正后的代码

data Event = AddEggs | AddFlour | AddSugar | Mix | Bake
  deriving (Eq, Show)

data State = Start | Error | Finished | HasEggs | HasFlour | HasSugar | HasFlourAndSugar | Mixed 
  deriving (Eq, Show)

-- 核心状态转换函数,处理单个事件的状态变更
step :: State -> Event -> State
-- 终止状态保持不变
step Error _ = Error
step Finished _ = Finished

-- 初始状态Start的转换
step Start AddEggs = HasEggs
step Start _ = Error  -- Start状态下只能加鸡蛋,其他操作直接报错

-- HasEggs状态的转换
step HasEggs AddFlour = HasFlour
step HasEggs AddSugar = HasSugar
step HasEggs _ = Error  -- HasEggs状态下只能加面粉或糖,其他操作报错

-- HasFlour状态的转换
step HasFlour AddSugar = HasFlourAndSugar
step HasFlour _ = Error  -- HasFlour状态下只能加糖,其他操作报错

-- HasSugar状态的转换
step HasSugar AddFlour = HasFlourAndSugar
step HasSugar _ = Error  -- HasSugar状态下只能加面粉,其他操作报错

-- HasFlourAndSugar状态的转换
step HasFlourAndSugar Mix = Mixed
step HasFlourAndSugar _ = Error  -- 该状态下只能搅拌,其他操作报错

-- Mixed状态的转换
step Mixed Bake = Finished
step Mixed _ = Error  -- Mixed状态下只能烘焙,其他操作报错

-- 兜底匹配(理论上不会触发)
step _ _ = Error

-- 遍历事件序列的函数(保持原代码不变)
bake :: [Event] -> State
bake events = go Start events
  where go state [] = state
        go state (e:es) = go (step state e) es

修正说明

  1. 语法错误修复:

    • 将所有制表符替换为空格,消除-Wtabs警告
    • 移除冗余的stepHelper函数,简化逻辑结构,避免参数传递导致的解析错误
  2. 逻辑错误修复:

    • 新增终止状态(Error/Finished)的固定转换规则,确保进入后状态不再变更
    • 完善每个状态的合法事件判断,严格遵循规则:
      • Start仅接受AddEggs
      • HasEggs仅接受AddFlour或AddSugar
      • HasFlour仅接受AddSugar,转换到HasFlourAndSugar
      • HasSugar仅接受AddFlour,转换到HasFlourAndSugar
      • HasFlourAndSugar仅接受Mix,转换到Mixed
      • Mixed仅接受Bake,转换到Finished
    • 所有非法事件直接触发Error状态,符合规则要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:42:50