Haskell功能与扑克牌(返回值的手)

时间:2018-01-02 15:49:16

标签: list haskell playing-cards

我正处于修订周,我正在尝试为Haskell考试撰写过去的论文。但是,这个功能是我无法应付的。

扑克牌的价值如下所示:   '2','3','4','5','6','7','8','9','T','J','Q','K','A ”。  一手牌可以写成一个字符串,例如“A563Q”。

我需要写一个函数 scoreHand :: [PlayingCardValue] - >诠释 这将返回一手牌中持有的总价值。 'A'的值为11.'T','J','Q'和'K'各自的值为10.其他数字的面值('2'的值为2,'3 '的值为3,依此类推。)

所以我应该写这个函数的两个版本。 第一个使用递归,没有库函数或列表理解,而第二个使用列表理解,库函数等反过来(a.k.a)。

我用递归编写了这个版本,但我正在与另一个版本进行斗争 版本

这是我的递归代码(即使我使用的是一个库函数,但我最终会弄清楚)

*

import Data.Char
type PlayingCardValue = Char
scoreHand :: [PlayingCardValue] -> Int
scoreHand [] = 0
scoreHand (x:xs) =
  if x > '1' && x < '9'
    then digitToInt x + scoreHand (xs)
    else if x == 'T' || x == 'J' || x == 'Q' || x == 'K'
      then 10 + scoreHand (xs)
        else if x == 'A'
          then 11 + scoreHand (xs)
          else 0 + scoreHand (xs)

* 关于如何创建不使用递归的相同函数的任何想法?

1 个答案:

答案 0 :(得分:5)

首先,我认为您可以通过引入 new 功能使代码更优雅:

score :: PlayingCardValue -> Int
score '2' = 2
score '3' = 3
score '4' = 4
score '5' = 5
score '6' = 6
score '7' = 7
score '8' = 8
score '9' = 9
score 'T' = 10
score 'J' = 10
score 'Q' = 10
score 'K' = 10
score 'A' = 11
score _ = 0

所以现在我们可以计算出一张卡片的分数。如果需要,我们可以使用digitToInt :: Char -> Int函数。如何计算单张卡的得分也更加清晰。

接下来我们可以使用递归:

scoreHand :: [PlayingCardValue] -> Int
scoreHand [] = 0
scoreHand (x:xs) = score x + scoreHand xs

如果我们想要写一个非递归的,我们可以使用map :: (a -> b) -> [a] -> [b]sum :: Num a => [a] -> a

scoreHand :: [PlayingCardValue] -> Int
scoreHand xs = sum (map score xs)

因此,使用map score xs,我们会创建一个新列表,对于列表xs中的每张卡片,我们有一个包含得分的元素,然后我们sum这些值。我们可以通过使用函数组合来更优雅地编写它:

scoreHand :: [PlayingCardValue] -> Int
scoreHand = sum . map score