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 testimport Fake
import qualified Fake.Person as Person
import qualified Fake.Internet as Internet
-- Deterministic generation
let name = runFakerSeed 42 Person.fullName
let email = runFakerSeed 42 Internet.email
-- Non-deterministic generation
randomName <- runFaker Person.fullNamedata User = User
{ name :: String
, email :: String
, age :: Int
} deriving (Show)
generateUser :: Fake User
generateUser = do
n <- Person.fullName
e <- Internet.email
a <- integerRange 18 80
return $ 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:
newtype Fake a = Fake (State StdGen a)
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,mapGen,flatMap
- 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
import Test.Hspec
import Fake
import qualified Fake.Person as Person
spec :: Spec
spec = describe "User generation" $ do
it "generates consistent names with same seed" $ do
let name1 = runFakerSeed 123 Person.fullName
let name2 = runFakerSeed 123 Person.fullName
name1 `shouldBe` name2Run tests:
cabal test