--------------------------------------------------------------------------
--
--  Haskell: The Craft of Functional Programming, 3e
--  Simon Thompson
--  (c) Addison-Wesley, 1996-2011.
-- 
--  Chapter 4
--
--------------------------------------------------------------------------

-- NOTE
--
-- Added HUnit and QuickCheck tests
--
-- HUnit 1.0 documentation is out of date
-- re package name.

module Chapter4 where

import Test.HUnit
import Test.QuickCheck
import PicturesSVG hiding (test2)

-- Designing a program in Haskell
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

maxThree :: Int -> Int -> Int -> Int
maxThree :: Int -> Int -> Int -> Int
maxThree Int
x Int
y Int
z = (Int
x Int -> Int -> Int
forall a. Ord a => a -> a -> a
`max` Int
y) Int -> Int -> Int
forall a. Ord a => a -> a -> a
`max` Int
z

testMax1 :: Test
testMax1 = Assertion -> Test
TestCase (String -> Int -> Int -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: maxThree 6 4 1" Int
6 (Int -> Int -> Int -> Int
maxThree Int
6 Int
4 Int
1))
testMax2 :: Test
testMax2 = Assertion -> Test
TestCase (String -> Int -> Int -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: maxThree 6 6 6" Int
6 (Int -> Int -> Int -> Int
maxThree Int
6 Int
6 Int
6))
testMax3 :: Test
testMax3 = Assertion -> Test
TestCase (String -> Int -> Int -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: maxThree 2 6 6" Int
6 (Int -> Int -> Int -> Int
maxThree Int
2 Int
6 Int
6))
testMax4 :: Test
testMax4 = Assertion -> Test
TestCase (String -> Int -> Int -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: maxThree 2 2 6" Int
6 (Int -> Int -> Int -> Int
maxThree Int
2 Int
2 Int
6))

-- run as 
--   runTestTT testsMax

testsMax :: Test
testsMax = [Test] -> Test
TestList [Test
testMax1, Test
testMax2, Test
testMax3, Test
testMax4]

-- NOTE
--
-- Added this type synonym so that can switch easily
-- between Integer and Int.

type MyNum = Integer

middleNumber :: MyNum -> MyNum -> MyNum -> MyNum
middleNumber :: Integer -> Integer -> Integer -> Integer
middleNumber Integer
x Integer
y Integer
z
  | Integer -> Integer -> Integer -> Bool
between Integer
y Integer
x Integer
z      = Integer
x
  | Integer -> Integer -> Integer -> Bool
between Integer
x Integer
y Integer
z      = Integer
y
  | Bool
otherwise          = Integer
z

-- What follows here is a dummy definition of between; you need to replace this
-- with a proper definition for the function middleNumber to work.

between ::  MyNum -> MyNum -> MyNum -> Bool

-- dummy definition 
-- for you to complete!

between :: Integer -> Integer -> Integer -> Bool
between = Integer -> Integer -> Integer -> Bool
between


-- NOTE
--
-- HUnit tests added
--
-- To run evaluate: runTestTT tests

test1 :: Test
test1 = Assertion -> Test
TestCase (String -> Bool -> Bool -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: between 2 3 4" Bool
True (Integer -> Integer -> Integer -> Bool
between Integer
2 Integer
3 Integer
4))
test2 :: Test
test2 = Assertion -> Test
TestCase (String -> Bool -> Bool -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: between 2 3 2" Bool
False (Integer -> Integer -> Integer -> Bool
between Integer
2 Integer
3 Integer
2))
test3 :: Test
test3 = Assertion -> Test
TestCase (String -> Bool -> Bool -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: between 2 3 3" Bool
True (Integer -> Integer -> Integer -> Bool
between Integer
2 Integer
3 Integer
3))
test4 :: Test
test4 = Assertion -> Test
TestCase (String -> Bool -> Bool -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: between 3 3 3" Bool
True (Integer -> Integer -> Integer -> Bool
between Integer
3 Integer
3 Integer
3))
test5 :: Test
test5 = Assertion -> Test
TestCase (String -> Bool -> Bool -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: between 3 2 3" Bool
False (Integer -> Integer -> Integer -> Bool
between Integer
3 Integer
2 Integer
3))
test6 :: Test
test6 = Assertion -> Test
TestCase (String -> Bool -> Bool -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: between 3 2 1" Bool
True (Integer -> Integer -> Integer -> Bool
between Integer
3 Integer
2 Integer
1))

testsBetween :: Test
testsBetween = [Test] -> Test
TestList [Test
test1, Test
test2, Test
test3, Test
test4, Test
test5, Test
test6]

-- NOTE
-- 
-- Interesting to vary the implementation and see which tests fail.
-- Simple form of mutation testing.

-- QuickCheck test
--
-- Does the tricky implementation of between work in the 
-- same way as the case analysis?

prop_between :: MyNum -> MyNum -> MyNum -> Bool

prop_between :: Integer -> Integer -> Integer -> Bool
prop_between Integer
x Integer
y Integer
z 
 = (Integer -> Integer -> Integer -> Bool
between Integer
x Integer
y Integer
z) Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== ((Integer
xInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<=Integer
y)Bool -> Bool -> Bool
&&(Integer
yInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<=Integer
z))Bool -> Bool -> Bool
||((Integer
xInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>=Integer
y)Bool -> Bool -> Bool
&&(Integer
yInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>=Integer
z))

-- Unit tests as Quick Check properties

prop_between1 :: Bool

prop_between1 :: Bool
prop_between1
 = Integer -> Integer -> Integer -> Bool
between Integer
2 Integer
3 Integer
4 Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
True

-- Local definitions
-- ^^^^^^^^^^^^^^^^^

-- Four ways of defining a Picture using 
-- different combinations of loca definitions.


fourPics1 :: Picture -> Picture

fourPics1 :: Picture -> Picture
fourPics1 Picture
pic =
    Picture
left Picture -> Picture -> Picture
`beside` Picture
right
      where
        left :: Picture
left  = Picture
pic Picture -> Picture -> Picture
`above` Picture -> Picture
invertColour Picture
pic
        right :: Picture
right = Picture -> Picture
invertColour (Picture -> Picture
flipV Picture
pic) Picture -> Picture -> Picture
`above` Picture -> Picture
flipV Picture
pic

fourPics2 :: Picture -> Picture
fourPics2 :: Picture -> Picture
fourPics2 Picture
pic =
    Picture
left Picture -> Picture -> Picture
`beside` Picture
right
      where
        left :: Picture
left    = Picture
pic Picture -> Picture -> Picture
`above` Picture -> Picture
invertColour Picture
pic
        right :: Picture
right   = Picture -> Picture
invertColour Picture
flipped Picture -> Picture -> Picture
`above` Picture
flipped
        flipped :: Picture
flipped = Picture -> Picture
flipV Picture
pic

fourPics3 :: Picture -> Picture

fourPics3 :: Picture -> Picture
fourPics3 Picture
pic =
    Picture
left Picture -> Picture -> Picture
`beside` Picture
right
      where
        left :: Picture
left  = Picture
pic Picture -> Picture -> Picture
`above` Picture -> Picture
invertColour Picture
pic
        right :: Picture
right = Picture -> Picture
invertColour (Picture -> Picture
flipV Picture
left)

fourPics4 :: Picture -> Picture

fourPics4 :: Picture -> Picture
fourPics4 Picture
pic =
    Picture
left Picture -> Picture -> Picture
`beside` Picture
right
      where
        stack :: Picture -> Picture
stack Picture
p  = Picture
p Picture -> Picture -> Picture
`above` Picture -> Picture
invertColour Picture
p
        left :: Picture
left     = Picture -> Picture
stack Picture
pic
        right :: Picture
right    = Picture -> Picture
stack (Picture -> Picture
invertColour (Picture -> Picture
flipV Picture
pic))

-- Area of a triangle

triArea' :: Float -> Float -> Float -> Float

triArea' :: Float -> Float -> Float -> Float
triArea' Float
a Float
b Float
c 
    | Bool
forall {t}. t
possible   = Float -> Float
forall a. Floating a => a -> a
sqrt(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
-Float
a)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
-Float
b)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
-Float
c))
    | Bool
otherwise  = Float
0
    where
      s :: Float
s = (Float
aFloat -> Float -> Float
forall a. Num a => a -> a -> a
+Float
bFloat -> Float -> Float
forall a. Num a => a -> a -> a
+Float
c)Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
2 
      possible :: t
possible = t
possible -- dummy definition

-- Sum of squares

sumSquares :: Integer -> Integer -> Integer

sumSquares :: Integer -> Integer -> Integer
sumSquares Integer
n Integer
m 
  = Integer
sqN Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
sqM
    where
    sqN :: Integer
sqN = Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
n
    sqM :: Integer
sqM = Integer
mInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
m


-- Let expressions
-- ^^^^^^^^^^^^^^^

-- Two examples which use `let'.

letEx1 :: Integer
letEx1 :: Integer
letEx1 = let x :: Integer
x = Integer
3Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
2 in Integer
xInteger -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
4

letEx2 :: Integer
letEx2 :: Integer
letEx2 = let x :: Integer
x = Integer
3Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
2 ; y :: Integer
y = Integer
5Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1 in Integer
xInteger -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
y


-- Scopes

isOdd, isEven :: Int -> Bool

isOdd :: Int -> Bool
isOdd Int
n 
  | Int
nInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<=Int
0        = Bool
False
  | Bool
otherwise   = Int -> Bool
isEven (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)

isEven :: Int -> Bool
isEven Int
n 
  | Int
nInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
0         = Bool
False
  | Int
nInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0        = Bool
True
  | Bool
otherwise   = Int -> Bool
isOdd (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)


-- Defining types for ourselves
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

-- Rock - Paper - Scissors

data Move = Rock | 
            Paper | 
            Scissors
            deriving Move -> Move -> Bool
(Move -> Move -> Bool) -> (Move -> Move -> Bool) -> Eq Move
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Move -> Move -> Bool
== :: Move -> Move -> Bool
$c/= :: Move -> Move -> Bool
/= :: Move -> Move -> Bool
Eq

-- Showing Moves in an abbreviated form.

instance Show Move where
      show :: Move -> String
show Move
Rock = String
"r"
      show Move
Paper = String
"p"
      show Move
Scissors = String
"s"

-- For QuickCheck to work over the Move type.

instance Arbitrary Move where
  arbitrary :: Gen Move
arbitrary     = [Move] -> Gen Move
forall a. HasCallStack => [a] -> Gen a
elements [Move
Rock, Move
Paper, Move
Scissors]

-- Calculating the Move to beat or lose against the 
-- argument Move.

beat, lose :: Move -> Move

beat :: Move -> Move
beat Move
Rock = Move
Paper
beat Move
Paper = Move
Scissors
beat Move
Scissors = Move
Rock

lose :: Move -> Move
lose Move
Rock = Move
Scissors
lose Move
Paper = Move
Rock
lose Move
Scissors = Move
Paper


-- Primitive recursion over Int
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

-- The factorial of n is 1*2*...*(n-1)*n, so that factorial of four is 24.
-- It is often written n!

fac :: Integer -> Integer
fac :: Integer -> Integer
fac Integer
n
  | Integer
nInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
0        = Integer
1
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
0         = Integer -> Integer
fac (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
n
  | Bool
otherwise   = String -> Integer
forall a. HasCallStack => String -> a
error String
"fac only defined on natural numbers"

--                                      n
-- Raising two to a power: power2 n is 2  in mathematical notation.

power2 :: Integer -> Integer
power2 :: Integer -> Integer
power2 Integer
n
  | Integer
nInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
0        = Integer
1
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
0         = Integer
2 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer -> Integer
power2 (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

-- The sum of the factorials up to a particular value, 0! + 1! + ... n!.

sumFacs :: Integer -> Integer
sumFacs :: Integer -> Integer
sumFacs Integer
n
  | Integer
nInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
0        = Integer
1
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
0         = Integer -> Integer
sumFacs (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer -> Integer
fac Integer
n  

-- The sum of the values of a function up to a particular value: 
--  f 0 + f 1 + ... f n
-- from which you can reconstruct sumFacs: sumFacs n = sumFun fac n

sumFun :: (Integer -> Integer) -> Integer -> Integer
sumFun :: (Integer -> Integer) -> Integer -> Integer
sumFun Integer -> Integer
f Integer
n
  | Integer
nInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
0        = Integer -> Integer
f Integer
0
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
0         = (Integer -> Integer) -> Integer -> Integer
sumFun Integer -> Integer
f (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer -> Integer
f Integer
n  

-- The maximum number of regions into which n lines can cut a plane.

regions :: Integer -> Integer 
regions :: Integer -> Integer
regions Integer
n
  | Integer
nInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
0        = Integer
1
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
0         = Integer -> Integer
regions (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
n

-- The Fibonacci numbers 0, 1, 1, 2, 3, 5, ..., u, v, u+v, ...

fib :: Integer -> Integer
fib :: Integer -> Integer
fib Integer
n 
  | Integer
nInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
0        = Integer
0
  | Integer
nInteger -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
==Integer
1        = Integer
1
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>Integer
1         = Integer -> Integer
fib (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
2) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer -> Integer
fib (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

-- Division of integers

remainder :: Integer -> Integer -> Integer
remainder :: Integer -> Integer -> Integer
remainder Integer
m Integer
n 
  | Integer
mInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<Integer
n         = Integer
m
  | Bool
otherwise   = Integer -> Integer -> Integer
remainder (Integer
mInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
n) Integer
n

divide    :: Integer -> Integer -> Integer
divide :: Integer -> Integer -> Integer
divide Integer
m Integer
n
  | Integer
mInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<Integer
n         = Integer
0
  | Bool
otherwise   = Integer
1 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer -> Integer -> Integer
divide (Integer
mInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
n) Integer
n

-- Testing
-- ^^^^^^^

-- Does this function calculate the maximum of three numbers?

mysteryMax :: Integer -> Integer -> Integer -> Integer
mysteryMax :: Integer -> Integer -> Integer -> Integer
mysteryMax Integer
x Integer
y Integer
z
  | Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
y Bool -> Bool -> Bool
&& Integer
x Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
z      = Integer
x
  | Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
x Bool -> Bool -> Bool
&& Integer
y Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
z      = Integer
y
  | Bool
otherwise           = Integer
z

testMMax1 :: Test
testMMax1 = Assertion -> Test
TestCase (String -> Integer -> Integer -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: mysteryMax 6 4 1" Integer
6 (Integer -> Integer -> Integer -> Integer
mysteryMax Integer
6 Integer
4 Integer
1))
testMMax2 :: Test
testMMax2 = Assertion -> Test
TestCase (String -> Integer -> Integer -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: mysteryMax 6 6 6" Integer
6 (Integer -> Integer -> Integer -> Integer
mysteryMax Integer
6 Integer
6 Integer
6))
testMMax3 :: Test
testMMax3 = Assertion -> Test
TestCase (String -> Integer -> Integer -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: mysteryMax 2 6 6" Integer
6 (Integer -> Integer -> Integer -> Integer
mysteryMax Integer
2 Integer
6 Integer
6))
testMMax4 :: Test
testMMax4 = Assertion -> Test
TestCase (String -> Integer -> Integer -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: mysteryMax 2 2 6" Integer
6 (Integer -> Integer -> Integer -> Integer
mysteryMax Integer
2 Integer
2 Integer
6))
testMMax5 :: Test
testMMax5 = Assertion -> Test
TestCase (String -> Integer -> Integer -> Assertion
forall a.
(HasCallStack, Eq a, Show a) =>
String -> a -> a -> Assertion
assertEqual String
"for: mysteryMax 6 6 2" Integer
6 (Integer -> Integer -> Integer -> Integer
mysteryMax Integer
6 Integer
6 Integer
2))


testsMMax :: Test
testsMMax = [Test] -> Test
TestList [Test
testMMax1, Test
testMMax2, Test
testMMax3, Test
testMMax4, Test
testMMax5]


-- Numbers of roots

numberNDroots :: Float -> Float -> Float -> Integer 

numberNDroots :: Float -> Float -> Float -> Integer
numberNDroots Float
a Float
b Float
c
    | Float
bsq Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
fac   = Integer
2
    | Float
bsq Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
fac  = Integer
1
    | Float
bsq Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
< Float
fac   = Integer
0
    where
      bsq :: Float
bsq = Float
bFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
b
      fac :: Float
fac = Float
4.0Float -> Float -> Float
forall a. Num a => a -> a -> a
*Float
aFloat -> Float -> Float
forall a. Num a => a -> a -> a
*Float
c 

-- Area of a triangle

triArea :: Float -> Float -> Float -> Float

triArea :: Float -> Float -> Float -> Float
triArea Float
a Float
b Float
c 
    | Float -> Float -> Float -> Bool
possible Float
a Float
b Float
c = Float -> Float
forall a. Floating a => a -> a
sqrt(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
-Float
a)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
-Float
b)Float -> Float -> Float
forall a. Num a => a -> a -> a
*(Float
sFloat -> Float -> Float
forall a. Num a => a -> a -> a
-Float
c))
    | Bool
otherwise      = Float
0
    where
      s :: Float
s = (Float
aFloat -> Float -> Float
forall a. Num a => a -> a -> a
+Float
bFloat -> Float -> Float
forall a. Num a => a -> a -> a
+Float
c)Float -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
2 

possible :: Float -> Float -> Float -> Bool

possible :: Float -> Float -> Float -> Bool
possible Float
a Float
b Float
c = Bool
True -- dummy definition

fact :: Int -> Int
  
fact :: Int -> Int
fact Int
n 
    | Int
nInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
1       = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int -> Int
fact (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
    | Bool
otherwise = Int
1

prop_fact :: Int -> Bool
prop_fact Int
n =
  Int -> Int
fact Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0

-- Extended exercise
-- ^^^^^^^^^^^^^^^^^

blackSquares :: Integer -> Picture

blackSquares :: Integer -> Picture
blackSquares Integer
n
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<=Integer
1         = Picture
black
  | Bool
otherwise = Picture
black Picture -> Picture -> Picture
`beside` Integer -> Picture
blackSquares (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

blackWhite :: Integer -> Picture

blackWhite :: Integer -> Picture
blackWhite Integer
n
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<=Integer
1         = Picture
black
  | Bool
otherwise = Picture
black Picture -> Picture -> Picture
`beside` Integer -> Picture
forall {t}. t
whiteBlack (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)

whiteBlack :: a
whiteBlack = String -> a
forall a. HasCallStack => String -> a
error String
"exercise for you"

blackChess :: Integer -> Integer -> Picture

blackChess :: Integer -> Integer -> Picture
blackChess Integer
n Integer
m
  | Integer
nInteger -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
<=Integer
1         = Integer -> Picture
blackWhite Integer
m
  | Bool
otherwise = Integer -> Picture
blackWhite Integer
m Picture -> Picture -> Picture
`above` Integer -> Integer -> Picture
forall {p} {p} {a}. p -> p -> a
whiteChess (Integer
nInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) Integer
m

whiteChess :: p -> p -> a
whiteChess p
n p
m = String -> a
forall a. HasCallStack => String -> a
error String
"exercise for you"