Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell的我自己的类型(数据类型2)中访问我自己的类型(数据类型)?_Haskell - Fatal编程技术网

在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
是模式匹配时指定的局部变量。