Fuzz.Category provides fuzz tests for common functions, like map
and andThen
.
Many Elm data structures share some similar functions. I'm sure you've noticed map
and andThen
. There's List.map
, Set.map
, Maybe.map
and so on. Since this is a very common pattern in Elm, you should provide them wherever they make sense for your own data structures, and use the functions in this module to make sure they behave as expected.
A common function for data structures in Elm is map : (a -> b) -> T a -> T b
for some type T
, such as List
or Set
. In mathematics, this is called a functor.
describe "List.map"
[ mapv1 List.map Fuzz.list
, mapv2 List.map Fuzz.list
, mapv3 List.map Fuzz.list
]
Functors follow two laws:
Identity: map identity = identity
, and
Composition: map (f << g) = map f << map g
.
mapv1 : ((Basics.Float -> Basics.Float) -> la -> la) -> (Fuzzer Basics.Float -> Fuzzer la) -> Test
This function helps you test your T.map
function, for every module T
you can think of.
mapv2 : ((String -> String) -> la -> la) -> (Fuzzer String -> Fuzzer la) -> Test
Another version of the map
test helper, with a new set of types.
mapv3 : ((List Char -> List Char) -> la -> la) -> (Fuzzer (List Char) -> Fuzzer la) -> Test
A third version of the map
test helper, with a third set of types.
Another common function for data structures in Elm is andThen : (a -> T b) -> T a -> T b
for some type T
, such as List
or Set
. In mathematics, this is called a monad.
describe "List.andThen"
[ andThenv1 List.singleton List.concatMap Fuzz.list
, andThenv2 List.singleton List.concatMap Fuzz.list
, andThenv3 List.singleton List.concatMap Fuzz.list
]
Monads follow three laws:
Left identity: singleton a |> andThen f ≡ f a
,
Right identity: m |> andThen singleton ≡ m
, and
Associativity: (m |> andThen f) |> andThen g ≡ m |> andThen (\x -> f x |> andThen g)
,
where m
is anything with the same type as singleton a
, and f
and g
are (a -> a)
functions.
andThenv1 : (Basics.Float -> fa) -> ((Basics.Float -> fa) -> fa -> fa) -> (Fuzzer Basics.Float -> Fuzzer fa) -> Test
This function helps you test your T.andThen
function, for every module T
you can think of.
andThenv2 : (String -> fa) -> ((String -> fa) -> fa -> fa) -> (Fuzzer String -> Fuzzer fa) -> Test
Another version of the andThen
test helper, with a new set of types.
andThenv3 : (List Char -> fa) -> ((List Char -> fa) -> fa -> fa) -> (Fuzzer (List Char) -> Fuzzer fa) -> Test
A third version of the map
test helper, with a third set of types.
Actually, the real laws aren't quite as strict as what I wrote above. In order to make the Elm type checker happy, I had to apply more constraints than the mathematical theory strictly requires. We're using endofunctors (a -> a)
instead of covariant functors (a -> b)
, for example.