gpt4 book ai didi

Haskell Prelude.head 错误,空列表

转载 作者:行者123 更新时间:2023-12-02 14:29:54 27 4
gpt4 key购买 nike

我的代码抛出空列表错误。当我运行时:

makeAgent :: Agent -> [Agent] -> Agent
makeAgent (Agent func n _) agents = (Agent func (n++(show $ length $ sameNames n agents)) empty) --appends number to name to differentiate agents
where sameNames n agents = filter (findName n) agents
findName n1 (Agent _ n2 _) = (slice 0 3 n1) == (slice 0 3 n2) --ignore the suffix
empty = head $ getEmpty (positions agents) (fst $ getGrid agents) --getGrid returns a tuple, but currently assume to be a square

baseline :: [Interaction] -> Float
baseline int = (fromIntegral total)/len
where total = sum sums
sums = map snd (showSums int)
agents = nub $ map (\(Interaction a1 a2 _ ) -> a2) int
len = fromIntegral $ length agents

reproduce :: Float -> [Interaction] -> [Agent] --so baseline isn't recalulated every time
reproduce _ [] = []
reproduce base interaction = winners ++ [newAgent] ++ reproduce base (tail interaction)
where agents = nub $ concat $ map (\(Interaction a1 a2 _ ) -> a1:a2:[]) interaction
winners = [a | a <- agents, (sumAgent interaction a) >= (round base)]
newAgent = makeAgent (head winners) winners


main = do
output "Length" (fromIntegral $ length int)
output "Baseline" base
output "Agents" agents
output "Sums" (showSums int)
output "winners" winners
output "NeAgent" (makeAgent (head winners)winners)
output "New Agents" (reproduce base int)

where agents = generate 4
int = playRound agents 20
base = baseline int
winners = [a | a <- agents, (sumAgent int a) >= (round base)]

这个重现(主要功能)应该做的是根据其 parent 的“适合度”是否超过一定水平来生成一个新的代理,然后对代理列表中除该代理之外的所有代理运行相同的函数。

它输出:

Length: 16
Baseline: 280.0
Agents: [c_pavlov(-1,-1),c_titForTat(-1,0),c_sucker(-1,1),b_grim(0,-1)]
Sums: [("c_pavlov",280),("c_titForTat",280),("c_sucker",280),("b_grim",280)]
winners: [c_pavlov(-1,-1),c_titForTat(-1,0),c_sucker(-1,1),b_grim(0,-1)]
NeAgent: c_pavlov1(0,0)
prisoners: Prelude.head: empty list

当我调用replicate时,它会抛出 prelude.head 空列表错误,并且 Winners、agent 和 int 列表都是非空的,因此这可能是递归最后一次迭代时的边缘情况错误。为什么会发生这种情况?

最佳答案

解决方案相对简单:只需在 Haskell 程序中不要使用 headtail 即可。 (虽然在某些情况下这样做是合理的,但最好一开始就假设不存在。)

相反,请使用模式匹配。通常,您总是希望在空列表和非空列表上进行正确的模式匹配,如下所示:

fun :: [Something] -> ...
fun [] = ...
fun (x : xs) = ... -- x is head, xs is tail

这样,您就被迫处理错误,并且您知道引用 xxs 不会再失败,因为该列表已被确定为非空。

如果您的程序中有很多列表永远不应该为空,那么您必须手动跟踪这些条件(并且至少应该记录它们)。但即便如此,最好在像这样的 let 绑定(bind)中进行模式匹配

(winner : _) = ...

然后稍后将 winner 引用为该列表的头部,因为您将收到一条错误消息,其中涉及模式匹配失败的行号。

关于Haskell Prelude.head 错误,空列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15285439/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com