-- Approximate the square root of $x to at least the accuracy of $eps
-- collecting the steps in a list.
squareRoot :: Double -> Double -> [Double]
squareRoot x eps | x < 0.0 = error "Non real answer."
| eps < 0.0 = error "Accuracy can't be more than perfect."
| otherwise = loop [((1 + x) / 2)] where
loop :: [Double] -> [Double]
loop (y:t) | abs((y * y) - x) <= eps = y : t
| otherwise = loop ((0.5*(y+(x/y))):y:t)
-- Just the head of this list.
-- I wonder if the compiler is capeable to optimize the list away ...
wurzel :: Double -> Double -> Double
wurzel x eps = head (squareRoot x eps)
-- How many approximations does it take to reach $eps accuracy
count :: Double -> Double -> Int
count x eps = length (squareRoot x eps)
sq :: Double -> Double
sq x = x * x
-- Trivial isn't it?
data Point = P Double Double deriving Show
add :: Point -> Point -> Point
add (P x1 y1) (P x2 y2) = P (x1+x2) (y1+y2)
distance :: Point -> Point -> Double
distance (P x1 y1) (P x2 y2) = sqrt ((sq (x1 - x2)) + (sq (y1 - y2)))
-- A shape has an area an can be moved.
class Shape a where
move :: a -> Point -> a
area :: a -> Double
-- Circles are shapes.
data Circle = C Point Double deriving Show
instance Shape Circle where
move (C middle radius) delta = C (add middle delta) radius
area (C middle radius) = pi * (sq radius)
-- As are Triangles.
data Triangle = T Point Point Point deriving Show
instance Shape Triangle where
move (T point1 point2 point3) delta =
T (add point1 delta) (add point2 delta) (add point3 delta)
area (T point1 point2 point3) =
sqrt (s * (s - a) * (s - b) * (s - c)) where
s = (a + b + c) / 2
a = distance point1 point2
b = distance point2 point3
c = distance point3 point1
-- and Rectangles.
data Rectangle = R Point Point deriving Show
instance Shape Rectangle where
move (R p1 p2) d =
R (add p1 d) (add p2 d)
area (R (P x1 y1) (P x2 y2)) =
abs((x1 - x2) * (x1 - y2))
-- Bits are Zero or One.
data Bit = Zero | One deriving (Eq, Show)
-- Encode an Int as a Bit.
enc1 :: Int -> Bit
enc1 x | x == 0 = Zero
| x /= 0 = One
-- Decode a Bit to an Int.
dec1 :: Bit -> Int
dec1 x | x == Zero = 0
| x == One = 1
-- Convert from one datatype to an other by replaceing
-- occurances of x with occurances y.
replace :: (Eq a) => [(a,b)] -> a -> b
replace [ ] _ = error "Undefined replacement"
replace ((a, b) : xs) x | a == x = b
| otherwise = replace xs x
-- Pretty selfexplaining isn't it?
encode :: Int -> [Bit]
encode n | n < 0 = error "Can't convert negative numbers."
| otherwise = convert n [] where
convert :: Int -> [Bit] -> [Bit]
convert 0 l = l
convert n l = convert (floor (fromIntegral n / 2))
((enc1 (mod n 2)):l)
decode :: [Bit] -> Int
decode l = foldl (\sum bit -> 2 * sum + (dec1 bit)) 0 l
display :: [Bit] -> String
display = map (replace [(Zero, '0'), (One, '1')])