{- Most everything in Haskell is a function. If it isn't data. 

 Church of Recursion
Recursion gets you everything you would want just as well as a Turing Machine 

a recursive definition of a list
    it's either null as in [] 
    or 
    constructed as in x:xs 
        with head x an element and tail xs as a list
            that we can then apply head to get x until 
                the xs = empty

FIRST IS CLEAR AND UNDERSTANDABLE 
THEN AND ONLY THEN SHOULD IT BE FASTER

Conditionals are required if wet want to do interesting stuff.
More Conditionals means, each branch requires testing in itself.

operator properties that matter: 
associativity If a binary operation is associative, repeated application of the operation produces the same result regardless how valid pairs of parenthesis are inserted in the expression 
identity In algebra, an identity or identity element of a set S with a binary operation  is an element e that, when combined with any element x of S, produces that same x. 
commutativity In mathematics, a binary operation is commutative if changing the order of the operands does not change the result.
distributivity 
zero 
idempotence  is the property of certain operations in mathematics and computer science, that can be applied multiple times without changing the result beyond the initial application.

-}
prop_sum :: Integral a => a -> Property
prop_sum n = n >= 0 ==> sum [1..n] == n * (n + 1) `div` 2 
prop_sum :: Integral a => a -> Property
prop_sum n = n >= 0 ==> sum [1..n] == n * (n + 1) `div` 2
prop_sum n = n >= 0 ==> sum [1..n] == n * (n + 1) `div` 2