【发布时间】:2020-08-15 18:11:24
【问题描述】:
好的,所以我有两种类型:
data Ingredient = Ingredient { potato :: String, amount :: Int, cookingTime :: Int }
data Soup = Soup { availableTime :: Int, recipe :: [Ingredient], shoppingList :: [Ingredient], canBeDone :: Bool }
现在,如果我想比较一种成分的“可用时间”和“烹饪时间”(基本上,如果我只有“可用时间”来煮整个汤,我就有足够的时间来烹饪该成分)。 如果我可以在汤中烹制配料,配料就会转移到购物清单列表中。 我该怎么做? 这是我想出的:
doIHaveTime :: Soup -> Soup
doIHaveTime Soup{availableTime = a, recipe = [Ingredient{cookingTime = b}] } = if a >= b then Soup{ shoppingList = b:xs } else show "Can't be done."
这种思维方式有意义吗? 这些是我得到的错误:
soupExample.hs:6:128: 错误: • 无法将类型“[Char]”与“Soup”匹配 预期类型:汤 实际类型:字符串 • 在表达式中:显示“无法完成”。 在表达式中: 如果 a >= b 那么 汤 {shoppingList = b : xs} 别的 显示“无法完成”。 在“doIHaveTime”的等式中: doIHaveTime (汤{availableTime = a,recipe = [Ingredient {cookingTime = b}]}) = 如果 a >= b 那么 汤 {shoppingList = b : xs} 别的 显示“无法完成”。 失败,已加载模块:无。
【问题讨论】:
-
recipe = [Ingredient{cookingTime = b}]将只处理具有 一种 成分的配方,并在其他情况下崩溃。你可以使用recipe = is来绑定整个列表,或者做两种情况,recipe = []和recipe = Ingredient{cookingTime = b} : is。 -
另外,
Soup -> Soup类型看起来是错误的,因为如果没有足够的时间,您不会返回汤。也许你想要Soup -> Maybe Soup? -
shoppingList可能不应该是Soup的一部分;那应该是Ingredients 的列表,独立于Soup需要的任何成分。 -
我应该提一下,记录字段访问是 Haskell 的弱点之一。一旦获得更多经验,您可能会想了解一些部分解决方案(尤其是 optics)。
标签: haskell