再一次,我不能把我的头绕在这块蛋糕上:
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
停止。
两个有效的状态序列是:
[AddEggs, AddFlour, AddSugar, Mix, Bake]
[AddEggs, AddSugar, AddFlour, Mix, Bake]
请注意,AddFlour
和AddSugar
可以以两种不同的顺序出现。此外,在Bake
之后,您可以添加更多事件,并且状态机仍保留在Finished
或Error
中。最后,如果状态顺序被破坏,它将进入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
运行MWE
1.克隆this repo
1.在my-haskell-mooc
cd
至exercises
中
1.运行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
2条答案
按热度按时间wbgh16ku1#
编译器警告是稍后出现错误的预兆。你把空格和制表符混在一起了,你做错了。缩进和对齐在Haskell中很重要。查看你的Github repo,看看这个函数是如何呈现的:
如果你不编辑,我保证它永远不会编译。它需要对齐。
看起来像在2c9877caf中向一堆行添加了制表符。它们中的大多数都是无害的,因为它们在注解中,但是如果您从不在源文件中插入制表符,那么您的生活会更轻松。
pjngdqdw2#
你的状态转换函数应该只带两个参数:当前状态和行动。一个单一的状态应该包含你到目前为止所做的所有信息。你有五个可以影响状态的操作,这意味着你至少有32个不同的状态。由于某些操作序列显然是无效的(您不能在添加所有成分之前进行烘焙),因此可以将其中许多状态折叠为
Error
状态。例如,不需要表示烘焙但未混合的配料集的状态。但是像HasEggsAndFlour
和HasEggs
(暗示缺少面粉)是两种不同的状态。与其立即枚举状态,不如开始定义step函数,看看需要定义哪些状态。比如说
定义状态的方式可能会有所不同。上面,我暗示了每个状态的单独的空值构造器。您可以将其分解为可以组合的更简单的类似布尔的状态(以避免布尔盲)。比如说