Elias Hernandis - 21 Jan 2020
The inner workings of QuickTest do not really matter. The important thing is coming up and writting properties to verify correctness.
Remember to explicitly write the types of the predicates so that QuickCheck can provide appropriate examples.
An expression is in WHNF if any of the following are true:
case ... of, then it will be reduced depending on the value of the constructor.map for arbitrary containers[] (List) where fmap = map,Maybe where fmap ≠ mapMaybe, but rather fmap f Nothing = Nothing, fmap   f (Just x) = f x, andIO where fmap comes from the IO Monad.fmap namely <$>, e.g. map (+1) [1..3] == (+1) <$>   [1..3].Control.Applicative module.MaybeListIOliftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c takes a binary function an lifts it to a function that operates on two functors.class Monoid a where
  mempty  :: a
  mappend :: a -> a -> a
  mconcat :: [a] -> a
  mconcat = foldr mconcat memptymappend using infix notation with <>.-- mempty is the identity element for <>
mempty <> x = x
x <> mempty = x
-- The <> operator is left and right associative
(x <> y) <> z = x <> (y <> z)Remember that each do block maps to a monad, and some monads don’t do what we intuitively think they do. Consider
where the list monad comes into place (think of list comprehensions in this case).