在Haskell的我自己的类型(数据类型2)中访问我自己的类型(数据类型)?
好的,我有两种类型:在Haskell的我自己的类型(数据类型2)中访问我自己的类型(数据类型)?,haskell,Haskell,好的,我有两种类型: data Ingredient = Ingredient { potato :: String, amount :: Int, cookingTime :: Int } data Soup = Soup { availableTime :: Int, recipe :: [Ingredient], shoppingList :: [Ingredient], canBeDone :: Bool } 现在,如果我想比较一种配料的“可用时间”和“烹饪时间”(基本上是如果我
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”的方程式中:
有时间吗
(汤{availableTime=a,配方=[配料{cookingTime=b}]})
=如果a>=b,则
汤{shoppingList=b:xs}
其他的
显示“无法完成”
失败,已加载模块:无
要处理汤中的多种成分,您可以使用
all::(a->Bool)->[a]->Bool
检查配方中的每种成分是否可以在可用时间内烹饪:
enoughTime = all ((>=available) . cookingTime) ingredients
然后必须在if
和else
分支中返回Soup
。总的来说,它可以如下所示:
doIHaveTime :: Soup -> Soup
doIHaveTime soup@Soup{ availableTime = available, recipe = ingredients }
= if enoughTime
-- add ingredients to shoppingList and set canBeDone to True
then soup { shoppingList = ingredients
, canBeDone = True }
-- clear shoppingList and set canBeDone to False
else soup { shoppingList = []
, canBeDone = False }
where enoughTime = all ((>=available) . cookingTime) ingredients
请注意,我使用了
soup@Soup{…}
进行模式匹配,同时将值存储在变量soup
中。这样,您只需修改两个字段shoppingList
和canBeDone
recipe=[配料{cookingTime=b}]
将只处理含有一种配料的配方,而在其他情况下会崩溃。您可以使用recipe=is
绑定整个列表,或者执行两种情况,recipe=[]
和recipe=component{cookingTime=b}:is
。此外,类型Soup->Soup
看起来是错误的,因为如果时间不够,您就不会返回汤。也许你想要汤->也许汤
?购物清单
不应该是汤
的一部分;这应该是一个配料
列表,与汤
所需的配料无关。我可能应该提到,记录字段访问是Haskell最薄弱的环节之一。有一些局部解决方案(特别是光学)你可能想在获得更多经验后了解。谢谢你的帮助,不过我还是遇到了一个错误。据我所知,在最后一行“where enoughTime=all(>=available).cookingTime)Components”中,所有内容都有一个函数,在本例中为>=,它测试当前成分在成分列表中的cookingTime是否大于或等于顶部指定的可用时间。(对吗?)。所以“all”从Soup数据类型(可用)和配料数据类型(cookingTime)中获取一个参数,并沿着列表(配料)运行它们。是吗?我的实际程序是在进程调度上工作的,而我只在最后一行得到一个错误。这些是数据类型:`Data Prozess=Prozess{pid::String,arrival::Int,computing::Int}派生(显示)数据状态=状态{new::[Prozess],run::Prozess,ready:[Prozess],time::Int,chart::String}`这是函数:update\u ready::State->State update\u readystate@State{time=t,new=process}=如果isReady--添加到就绪状态列表,则状态为{ready=process}--else清除列表else状态{ready=[]},其中isReady=all(>=time).arrival)进程只需将=time
更改为=t
time
是成员函数,t
是模式匹配时指定的局部变量。