0

嗨,我在总结我的牌时遇到问题,因为 A 可以是 1 或 11。我怎样才能创建一个函数来处理一手牌,即 [Card] 并计算总值?

这是我到目前为止所拥有的:

handValue :: [Card]->[Int]
handValue [] = 0
handValue (x:xs) = sum((val x)++([handValue xs]))

其中 val 已经定义并从卡片返回一个值数组。例如 val ("Ace","Hearts") 给出 [1,11] val ("Five","Hearts") 给出 [5]

任何指针将不胜感激。

编辑:在重复建议后我有这个:

    handValue :: [Card]->[Int]
handValue [] = 0
handValue (x:xs) = 
            if (val x ==[1,11])
            then    (map sum (sequence [[1,11], handValue xs]))
                else [ sum [(val x)]++([handValue xs])]
4

2 回答 2

1

除了修复您的功能之外,您还应该首先注意它为什么不起作用。首先,你给的类型是

handValue :: [Card] -> [Int]

但是您的递归定义具有单个值,而不是列表,作为结果类型(0第一个等式中的文字;第二个等式中的使用sumNum a => [a] -> a

现在,假设类型更改为[Card] -> Int,您的定义将是合法的,但结果会很奇怪。你的第二个等式是:

handValue (x:xs) = sum((val x)++([handValue xs]))

如果x是 ace 会发生什么?val x将是[1, 11],因此两个值将被连接并包含在总和中。实际上,您的 A 现在不是 1 或 11,而是 12 点!nm 的解决方案,我在这里解释为

Prelude> map sum . sequence $ [[1,11], [5], [6]]
[12,22]

通过为所有可能的 ace 选择生成值列表 ( sequence) 并分别对所有可能性求和( ) 来绕过问题map sum,从而产生一个值列表(如您最初给出的签名中所示)。但是,这并不能完全解决问题,因为您最终需要决定其中一种可能性。现在我们可能有足够的材料来回答一个不同的问题,一旦你到达那个点......

于 2013-10-25T18:35:09.470 回答
1
Prelude Control.Monad> liftM sum . sequence $ [[1,11], [5], [6]]
[12,22]
于 2013-10-25T17:32:24.037 回答