Haskell蛋糕烘焙状态机step函数参数数量错误排查
Haskell蛋糕烘焙状态机编译错误修复
错误原因分析
编译报错的核心问题是**step函数的等式参数数量不一致**,同时存在构造器参数不匹配、模式匹配错误:
- 某行
step定义仅传入了State参数,未接收Event参数,违反了step :: State -> Event -> State的类型签名,导致参数数量不匹配。 State类型的InProgress构造器仅接受4个参数(Egged、Floured、Sugared、Mixed),但代码中错误传入了5个参数(多了Unbaked)。- 最后一行
step Mixed Bake = Finished模式错误,Mixed是Mixed类型的值,不是State类型的构造器,无法直接匹配State。
修正后的完整代码
------------------------------------------------------------------------------ -- Ex 3: a state machine for baking a cake. The type Event represents -- things that can happen while baking a cake. The type State is meant -- to represent the states a cake can be in. -- -- Your job is to -- -- * add new states to the State type -- * and implement the step function -- -- so that they have the following behaviour: -- -- * Baking starts in the Start state -- * A successful cake (reperesented by the Finished value) is baked -- by first adding eggs, then adding flour and sugar (flour and -- sugar can be added in which ever order), then mixing, and -- finally baking. -- * If the order of Events differs from this, the result is an Error cake. -- No Events can save an Error cake. -- * Once a cake is Finished, it stays Finished even if additional Events happen. -- -- The function bake just calls step repeatedly. It's used for the -- examples below. Don't modify it. -- -- Examples: -- bake [AddEggs,AddFlour,AddSugar,Mix,Bake] ==> Finished -- bake [AddEggs,AddFlour,AddSugar,Mix,Bake,AddSugar,Mix] ==> Finished -- bake [AddFlour] ==> Error -- bake [AddEggs,AddFlour,Mix] ==> Error data Event = AddEggs | AddFlour | AddSugar | Mix | Bake deriving (Eq, Show) data Egged = HasEggs | HasNoEggs deriving (Eq, Show) data Floured = HasFlour | HasNoFlour deriving (Eq, Show) data Sugared = HasSugar | HasNoSugar deriving (Eq, Show) data Mixed = Mixed | Unmixed deriving (Eq, Show) data State = Start | Finished | Error | InProgress Egged Floured Sugared Mixed deriving (Eq, Show) step :: State -> Event -> State step Error _ = Error -- 错误状态无法恢复 step Finished _ = Finished -- 完成状态保持不变 step Start AddEggs = InProgress HasEggs HasNoFlour HasNoSugar Unmixed -- 第一步必须加鸡蛋 step Start _ = Error -- 第一步不是加鸡蛋直接报错 -- 已加鸡蛋的状态下添加面粉 step (InProgress HasEggs HasNoFlour sugar Unmixed) AddFlour = InProgress HasEggs HasFlour sugar Unmixed -- 已加鸡蛋的状态下添加糖 step (InProgress HasEggs flour HasNoSugar Unmixed) AddSugar = InProgress HasEggs flour HasSugar Unmixed -- 已加鸡蛋、面粉和糖的状态下搅拌 step (InProgress HasEggs HasFlour HasSugar Unmixed) Mix = InProgress HasEggs HasFlour HasSugar Mixed -- 已搅拌完成的状态下烘焙 step (InProgress HasEggs HasFlour HasSugar Mixed) Bake = Finished -- 兜底:所有不符合流程的操作都进入错误状态 step _ _ = Error -- 不要修改此函数 bake :: [Event] -> State bake events = go Start events where go state [] = state go state (e : es) = go (step state e) es main :: IO () main = do print (bake [AddEggs, AddFlour, AddSugar, Mix, Bake]) print (bake [AddEggs, AddFlour, AddSugar, Mix, Bake, AddSugar, Mix]) print (bake [AddFlour]) print (bake [AddEggs, AddFlour, Mix])
关键修正说明
- 移除了多余的
Baked类型,烘焙完成后直接进入Finished状态,无需额外维护该状态。 - 确保所有
step等式都接收两个参数(State和Event),匹配类型签名要求。 - 为每个合法操作流程编写了明确的模式匹配,支持面粉和糖的添加顺序任意。
- 添加兜底的
step _ _ = Error,覆盖所有不符合流程的操作,避免遗漏情况。 - 修正了
InProgress构造器的参数数量错误,确保仅传入定义好的4个参数。
内容的提问来源于stack exchange,提问作者coderodde
相关产品推荐
相关产品推荐

