【问题标题】:Haskell function with deck of playing cards (returning value of hand)带有扑克牌的 Haskell 函数(手牌的返回值)
【发布时间】:2018-01-02 15:49:16
【问题描述】:

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

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

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

所以我应该写这个函数的两个版本。 第一个使用递归,没有库函数或列表解析,第二个使用列表解析、库函数等。

我用递归编写了这个版本,但我正在努力解决另一个问题 版本。

这是我的递归代码(尽管我使用的是一个库函数,但我最终会弄明白的)

*

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)

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

【问题讨论】:

  • 不应该是x &lt;= '9',而不是x &lt; 9吗?

标签: list haskell playing-cards


【解决方案1】:

首先我认为你可以通过引入一个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 -&gt; Int 函数。单张牌的分数计算方式也更加简洁。

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-11
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多