这个函数是要找出列表A中有多少元素小于列表B中的最小元素
每次递归发生时,A的长度列表都会减少直到emepty。
然而......它只返回Exception:Prelude.head:空列表 甚至不是0 ..
为什么会这样?
compareSmall::[Card] -> [Card] -> Int
compareSmall [] _ = 0
compareSmall _ [] = 0
compareSmall (x:xs) (y:ys) =
if rank (head tnt1) < rank (head tnt2) then
1 + compareSmall (tail tnt1) (tnt2)
else if rank (head (tail tnt1)) == rank (head tnt2) then
0 + compareSmall (tail tnt1) (tnt2)
else
0 + compareSmall (tail tnt1) (tnt2)
where tnt1 = rankCard (x:xs)
tnt2 = rankCard (y:ys)
答案 0 :(得分:1)
您的问题在于rankCard
返回一个空列表,因此tnt1
或tnt2
在某个时刻是[]
。然后在执行head tnt1
时收到错误,因为head
是部分函数,并且会在空列表而不是Maybe
上抛出异常。
调用else if rank (head (tail tnt1)) == rank (head tnt2) then
发生了这种情况,特别是(head (tail tnt1))
在tnt1
是包含1个元素的列表时发出错误。
似乎你不需要你的第二个if语句,因为你永远不会修改你的tnt2
列表,因此通过让递归运行一次并且不会抛出任何错误,它将被捕获到最后的其他语句。你的代码可能只是
compareSmall :: [Card] -> [Card] -> Int
compareSmall [] _ = 0
compareSmall _ [] = 0
compareSmall a b =
if rank (head tnt1) < rank (head tnt2) then
1 + compareSmall (tail tnt1) b
else
0 + compareSmall (tail tnt1) b
where
tnt1 = rankCard a
tnt2 = rankCard b
旁注:Haskell具有在模式匹配时保留整个列表的语法,所以你可以这样做
compareSmall a@(x:xs) b@(y:ys) =
...
where
tnt1 = rank a
tnt2 = rank b
如果你需要那个。