дени коефициенти

countRoots :: (Ord a, Floating a) => a -> a -> a -> String
countRoots a b c
  | d < 0     = "no roots"
  | d == 0    = "one root"
  | otherwise = "two roots"
  where d = b*b - 4*a*c


--Task 4

--Отделните аргументи може да са различни типове с различни ограничения.

power :: (Num a, Integral b) => a -> b -> a
power base n
  | n == 0    = 1
  | even n    = square (power base (div n 2))
  | otherwise = base * square (power base (div n 2))
  where square x = x*x


--Task 5

cylinderVolume :: Floating a => a -> a -> a
cylinderVolume r h = pi * r^2 * h

fib' :: (Integral a) => a -> a
fib' n
  | n < 0 = 0
  | otherwise = fibHelper 0 1 startIdx
  where fibHelper f1 f2 i
          | i == n = f1
          | otherwise = fibHelper f2 (f1+f2) (i+1)
        startIdx = 0


--Pattern matching - разписваме граничните случаи като отделни дефиниции.
--Искаме те да бъдат преди "общия случай" на функцията по същата логика,
--по която правим първо проверките в рекурсивната функция - нов е само синтаксиса.
fib' n
  | n < 0 = 0
  | otherwise = fibHelper 0 1 startIdx
  where fibHelper f1 f2 i
          | i == n = f1
          | otherwise = fibHelper f2 (f1+f2) (i+1)
        startIdx = 0


--Pattern matching - разписваме граничните случаи като отделни дефиниции.
--Искаме те да бъдат преди "общия случай" на функцията по същата логика,
--по която правим първо проверките в рекурсивната функция - нов е само синтаксиса.