計算機科学のブログ

コンテキストでの型の操作 コンテキストとしてのリスト:Applicative型クラスをさらに掘り下げる 例:大量のテストデータをすばやく生成する 非決定論的な計算

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT5(コンテキストでの型の操作)、LESSON 29(コンテキストとしてのリスト:Applicative型クラスをさらに掘り下げる)、29.3(コンテキストとしてのリスト)、例:大量のテストデータをすばやく生成するのクイックチェック 29-5の解答を求めてみる。

コード

data User = User {
    name :: String,
    gamerId :: Int,
    score :: Int
} deriving Show

testNames :: [String]
testNames = [ "John Smith",
              "Robert'); drop table students;--",
              "Christine NULL",
              "Randall Munroe",
              "kamimura"]

testIds :: [Int]
testIds = [1337,
           0123,
           9999]

testScores :: [Int]
testScores = [0,
              100000,
              -9999]

testData :: [User]
testData = pure User <*> testNames <*> testIds <*> testScores

-- サンプル数は5 x 3 x 3 = 45個
main :: IO ()
main = do
    print (length testData)
    mapM_ print testData

入出力結果(Terminal, Zsh)

% runghc sample05.hs
45
User {name = "John Smith", gamerId = 1337, score = 0}
User {name = "John Smith", gamerId = 1337, score = 100000}
User {name = "John Smith", gamerId = 1337, score = -9999}
User {name = "John Smith", gamerId = 123, score = 0}
User {name = "John Smith", gamerId = 123, score = 100000}
User {name = "John Smith", gamerId = 123, score = -9999}
User {name = "John Smith", gamerId = 9999, score = 0}
User {name = "John Smith", gamerId = 9999, score = 100000}
User {name = "John Smith", gamerId = 9999, score = -9999}
User {name = "Robert'); drop table students;--", gamerId = 1337, score = 0}
User {name = "Robert'); drop table students;--", gamerId = 1337, score = 100000}
User {name = "Robert'); drop table students;--", gamerId = 1337, score = -9999}
User {name = "Robert'); drop table students;--", gamerId = 123, score = 0}
User {name = "Robert'); drop table students;--", gamerId = 123, score = 100000}
User {name = "Robert'); drop table students;--", gamerId = 123, score = -9999}
User {name = "Robert'); drop table students;--", gamerId = 9999, score = 0}
User {name = "Robert'); drop table students;--", gamerId = 9999, score = 100000}
User {name = "Robert'); drop table students;--", gamerId = 9999, score = -9999}
User {name = "Christine NULL", gamerId = 1337, score = 0}
User {name = "Christine NULL", gamerId = 1337, score = 100000}
User {name = "Christine NULL", gamerId = 1337, score = -9999}
User {name = "Christine NULL", gamerId = 123, score = 0}
User {name = "Christine NULL", gamerId = 123, score = 100000}
User {name = "Christine NULL", gamerId = 123, score = -9999}
User {name = "Christine NULL", gamerId = 9999, score = 0}
User {name = "Christine NULL", gamerId = 9999, score = 100000}
User {name = "Christine NULL", gamerId = 9999, score = -9999}
User {name = "Randall Munroe", gamerId = 1337, score = 0}
User {name = "Randall Munroe", gamerId = 1337, score = 100000}
User {name = "Randall Munroe", gamerId = 1337, score = -9999}
User {name = "Randall Munroe", gamerId = 123, score = 0}
User {name = "Randall Munroe", gamerId = 123, score = 100000}
User {name = "Randall Munroe", gamerId = 123, score = -9999}
User {name = "Randall Munroe", gamerId = 9999, score = 0}
User {name = "Randall Munroe", gamerId = 9999, score = 100000}
User {name = "Randall Munroe", gamerId = 9999, score = -9999}
User {name = "kamimura", gamerId = 1337, score = 0}
User {name = "kamimura", gamerId = 1337, score = 100000}
User {name = "kamimura", gamerId = 1337, score = -9999}
User {name = "kamimura", gamerId = 123, score = 0}
User {name = "kamimura", gamerId = 123, score = 100000}
User {name = "kamimura", gamerId = 123, score = -9999}
User {name = "kamimura", gamerId = 9999, score = 0}
User {name = "kamimura", gamerId = 9999, score = 100000}
User {name = "kamimura", gamerId = 9999, score = -9999}
%