2017-10-13 18 views
1

私は代数データ型のReal World Haskell Chapter 11quickCheckジェネレータの実装に苦労しています。ハスケルの任意の文字列ジェネレータ(Test.QuickCheck.Gen)

(2008年に出版された)の本実装後、私は次のを思い付いた:

-- file: ch11/Prettify2.hs 
module Prettify2(
    Doc(..) 
) where 

data Doc = Empty 
     | Char Char 
     | Text String 
     | Line 
     | Concat Doc Doc 
     | Union Doc Doc 
     deriving (Show, Eq) 

そして、私の任意の実装:

-- file: ch11/Arbitrary.hs 

import System.Random 
import Test.QuickCheck.Gen 
import qualified Test.QuickCheck.Arbitrary 


class Arbitrary a where 
    arbitrary :: Gen a 
    -- elements' :: [a] => Gen a {- Expected a constraint, but ‘[a]’ has kind ‘*’ -} 
    -- choose' :: Random a => (a, a) -> Gen a 
    -- oneof' :: [Gen a] -> a 

data Ternary = Yes 
      | No 
      | Unknown 
      deriving(Eq, Show) 

instance Arbitrary Ternary where 
    arbitrary = do 
     n <- choose (0, 2) :: Gen Int 
     return $ case n of 
         0 -> Yes 
         1 -> No 
         _ -> Unknown 

instance (Arbitrary a, Arbitrary b) => Arbitrary (a, b) where 
    arbitrary = do 
     x <- arbitrary 
     y <- arbitrary 
     return (x, y) 

instance Arbitrary Char where 
    arbitrary = elements (['A'..'Z'] ++ ['a' .. 'z'] ++ " [email protected]#$%^&*()") 

ノーと2次の実装を試してみました成功:

import Prettify2 
import Control.Monad(liftM, liftM2) 

instance Arbitrary Doc where 
    arbitrary = do 
     n <- choose (1,6) :: Gen Int 
     case n of 
      1 -> return Empty 
      2 -> do x <- arbitrary 
        return (Char x) 
      3 -> do x <- arbitrary 
        return (Text x) 
      4 -> return Line 
      5 -> do x <- arbitrary 
        y <- arbitrary 
        return (Concat x y) 
      6 -> do x <- arbitrary 
        y <- arbitrary 
        return (Union x y) 

instance Arbitrary Doc where 
    arbitrary = 
     oneof [ return Empty 
       , liftM Char arbitrary 
       , liftM Text arbitrary 
       , return Line 
       , liftM2 Concat arbitrary arbitrary 
       , liftM2 Union arbitrary arbitrary ] 

ただし、以降はコンパイルされません。

私は次の方法でArbitrary Stringのインスタンスを実装するために、次に試してみました:

  • import qualified Test.QuickCheck.Arbitrary

    それは 任意Test.RandomStringshackage link

    インスタンス任意の文字列をインストールArbitrary String

  • どちらを実装していません。 = do n < - choose(8,16):: Gen Int リターン$ randomWord randomASCIIのn ::ゲン文字列

次バックトレース付:

$ ghci 
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help 
Prelude> :l Arbitrary.hs 
[1 of 2] Compiling Prettify2  (Prettify2.hs, interpreted) 
[2 of 2] Compiling Main    (Arbitrary.hs, interpreted) 

Arbitrary.hs:76:9: 
    The last statement in a 'do' block must be an expression 
     return <- randomWord randomASCII n :: Gen String 
Failed, modules loaded: Prettify2 

は、あなたがこの特定のジェネレータを実装する方法についての良い提案を持っているだろう - より一般的に - どのようにこれらの場合に進む?

ではなくTest.QuickCheckをインポートし、新しいArbitrary型クラスを定義しないでください、事前

答えて

2

でいただきありがとうございます。それはあなたのためにこれらのインスタンスのほとんどを定義します。またquickcheckのバージョンに注意して、RWHはバージョン1

結果の完全な実装がされる前提としています

-- file: ch11/Arbitrary.hs 

import Test.QuickCheck 
import Prettify2 
import Control.Monad(liftM, liftM2) 

data Ternary = Yes 
      | No 
      | Unknown 
      deriving(Eq, Show) 

instance Arbitrary Ternary where 
    arbitrary = do 
     n <- choose (0, 2) :: Gen Int 
     return $ case n of 
         0 -> Yes 
         1 -> No 
         _ -> Unknown 


instance Arbitrary Doc where 
    arbitrary = 
     oneof [ return Empty 
       , liftM Char arbitrary 
       , liftM Text arbitrary 
       , return Line 
       , liftM2 Concat arbitrary arbitrary 
       , liftM2 Union arbitrary arbitrary ] 
+0

RWOを?通常、RWHと略されています。 – Zeta

+0

ああ、私はOCamlと混同しました。 –

関連する問題