A pure, composable Haskell faker library for generating fake data in tests. Built with the State monad for deterministic, reproducible test data generation.
- Pure Functions: No global state or I/O effects in generators
- Deterministic: Seeded generation for reproducible tests
- Composable: Monadic combinators for building complex generators
- Type Safe: Concrete return types, no stringly-typed APIs
- Minimal Dependencies: Only standard Haskell libraries
- Easy to Use: Simple, intuitive API
cabal build
cabal testimportFakeimportqualifiedFake.PersonasPersonimportqualifiedFake.InternetasInternet-- Deterministic generationlet name = runFakerSeed 42Person.fullName
let email = runFakerSeed 42Internet.email
-- Non-deterministic generation
randomName <- runFaker Person.fullNamedataUser=User{name::String
, email::String
, age::Int}deriving (Show)
generateUser::FakeUser
generateUser =do
n <-Person.fullName
e <-Internet.email
a <- integerRange 1880return$User n e a
user <- runFaker generateUser-- Generate 5-10 emails
emails <- runFaker $ vectorOf (5, 10) Internet.email
-- Optional value (50% chance)
username <- runFaker $ maybeGen Internet.username
-- Pick one from list
email <- runFaker $ oneof [Internet.safeEmail, Internet.freeEmail]The library uses a State monad wrapping StdGen for pure, composable random generation:
newtypeFakea=Fake (StateStdGena)
deriving (Functor, Applicative, Monad)Three execution modes:
runFaker :: Fake a -> IO a- System randomrunFakerSeed :: Int -> Fake a -> a- DeterministicrunFakerWith :: StdGen -> Fake a -> a- Custom RNG
- Numbers:
integer,integerRange,natural,float,double,bool - Characters:
char,alpha,numeric,alphanumeric - Strings:
string,stringBounded - Selection:
elements,shuffle
- Repetition:
vector,vectorOf,sequence - Optionality:
maybeGen,oneof - Functional:
filterGen
- Names:
firstName,lastName,fullName,name - Titles:
title,jobTitle,prefix,suffix - Bio:
bio
- Email:
email,safeEmail,freeEmail - Usernames:
username,domain,domainSuffix - URLs:
url,slug
- Geography:
city,country,countryCode - Postal:
postalCode,zipCode - Coordinates:
latitude,longitude
importTest.HspecimportFakeimportqualifiedFake.PersonasPersonspec::Spec
spec = describe "User generation"$do
it "generates consistent names with same seed"$dolet name1 = runFakerSeed 123Person.fullName
let name2 = runFakerSeed 123Person.fullName
name1 `shouldBe` name2Run tests:
cabal test