3

首先这是家庭作业,所以请不要放弃太多!我需要理解这一点,而不是复制别人的代码。

我必须创建一副牌。而且我已经获得了可以使用的代码,但我无法让它们工作。我的意思是我可以在 2012-2013 年的演出中创造出最好的牌组,但这对我没有帮助,因为我需要使用我们提供的代码,而且我不能更改它。

(我使用 Read 和 Enum 来创建一副纸牌,看起来很棒,但我不能完成这个任务)

最后我收到一些错误消息,你可以看到。

   import Test.QuickCheck

    --DECK OF CARDS

    data Suit = Hearts | Spades | Diamonds | Clubs
       deriving (Eq, Show)

    data Card = Card Rank Suit
        deriving (Eq, Show)

    data Rank = Numeric Integer | Jack | Queen | King | Ace
        deriving (Eq, Show)

    instance Arbitrary Rank where
    arbitrary = frequency [ (1, return Jack)
                    , (1, return Queen)
                    , (1, return King)
                    , (1, return Ace)
                    , (9, do n <- choose (2, 10)
                             return (Numeric n))

                    ]

     --MY OWN CODE

     type Deck = [Card]
     deck :: Deck
     deck = [Card v s | v <- arbitrary Rank, s <- Suit]

当我尝试加载它时,我得到:

   Prelude> :l test4
   [1 of 1] Compiling Main             ( test4.hs, interpreted )

   test4.hs:31:35: Not in scope: data constructor `Rank'

   test4.hs:31:46: Not in scope: data constructor `Suit'
   Failed, modules loaded: none.

我哪里错了?我错过了一些基本的东西吗?如果是这样,我在哪里阅读它?

我将不胜感激任何和所有的建议和想法!

4

2 回答 2

3

我会指出您的代码存在几个问题:

  • 的类型arbitraryarbitrary :: Arbitrary a => Gen a。所以你需要一些东西来运行这个生成器来获取随机列表。

  • Rank并且Suit是类型而不是一些值。此外,您还需要显式指定类型arbitrary以获取该类型的生成器。likearbitrary :: (Gen Rank)然后使用类似sample'或其他函数运行以实际获得随机排名。

  • 同样,您需要为 和 定义任意Card实例。然后你可以通过只类型转换来生成SuitDeckDeckarbitraryGen Deck

  • 更多的是逻辑缺陷。您的任意实例将无法保证限制,例如一副牌中应该有 4 个国王等。因此,在为您定义任意实例时,Deck应该注意这一点。

  • Test.QuickCheck定义arbitrary实例时参考函数的类型。只需查看类型,您就会得到大部分正确的东西。

于 2012-09-13T18:23:15.330 回答
2

看起来你确实有一个基本的误解:在你的列表理解中,你试图使用RankSuit喜欢列表,但它们不是——它们是类型名称。如果你想遍历一组西装,你需要自己做一个。

在表达式中,大写的标识符应该是数据构造函数(因为类型在该上下文中没有任何意义)。编译器错误在这里并不是特别有用——它在数据构造函数命名空间中查找,但没有找到它们RankSuit

于 2012-09-13T18:32:01.097 回答