首页 > 解决方案 > 如何将每个值从一个列表映射到另一个?(哈斯克尔)

问题描述

这是我到目前为止的代码:

data Suit = Diamond | Club | Heart | Spade
  deriving (Read, Enum, Eq, Bounded)

data Rank = Two | Three | Four
     | Five | Six | Seven | Eight | Nine | Ten 
     | Jack | Queen | King | Ace
  deriving (Read, Enum, Eq, Ord, Bounded)

我正在尝试将每个值(Rank 或 Suit)映射到一个唯一的素数。

primeMapper :: Either Rank Suit -> Int

应该是最后一个函数,我想遍历每个 Suit 并将其设置为前四个素数:

primeMapper [Diamond .. Spade] = [2,3,5,7]

并且每个 Rank 等于 17 号之前的其余素数:

primeMapper [Two .. Ace] = drop 4 . take 17 $ primes

假设我有一个称为素数的生成函数。

然而,这段代码显然会抛出错误,因为它会从列表中生成一个列表。我怎样才能实现我想要做的事情?让我知道我是否可以更好地解释它。

最终目标是拥有一个哈希表,根据素因数为每张牌赋予唯一的 ID,然后生成素因数分解并使用模数来快速比较扑克手牌。

标签: listhaskellprimespoker

解决方案


您使用模式匹配的解决方案是最好的,但我更喜欢

primeMapper :: Either Suit Rank -> Int
primeMapper (Left Diamond) = 2
primeMapper (Left Club)    = 3
...

而不是你冗长的case表情。

但是你也可以使用lookup :: Eq a => a -> [(a, b)] -> Maybe b

import Data.Maybe (fromJust)

primeMapper :: Either Suit Rank -> Int
primeMapper = fromJust . flip lookup zippedPrimes
  where
  zippedPrimes = zip suitranks primes
  suitranks    = fmap Left suits ++ fmap Right ranks :: [Either Suit Rank]
  suits        = fromEnum minBound
  ranks        = fromEnum minBound

推荐阅读