{-# LANGUAGE LambdaCase #-}

{-# OPTIONS_HADDOCK hide #-}

-- |
-- Copyright: © 2018-2024 Intersect MBO
-- License: Apache-2.0
--
-- Provides internal types and functions relating to rounding of fractional
-- numbers.
--
module Internal.Rounding
    ( RoundingDirection (..)
    , round
    ) where

import Prelude hiding ( round )

-- | Indicates a rounding direction to be used when converting from a
--   fractional value to an integral value.
--
-- See 'round'.
--
data RoundingDirection
    = RoundUp
      -- ^ Round up to the nearest integral value.
    | RoundDown
      -- ^ Round down to the nearest integral value.
    deriving (RoundingDirection -> RoundingDirection -> Bool
(RoundingDirection -> RoundingDirection -> Bool)
-> (RoundingDirection -> RoundingDirection -> Bool)
-> Eq RoundingDirection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RoundingDirection -> RoundingDirection -> Bool
== :: RoundingDirection -> RoundingDirection -> Bool
$c/= :: RoundingDirection -> RoundingDirection -> Bool
/= :: RoundingDirection -> RoundingDirection -> Bool
Eq, Int -> RoundingDirection -> ShowS
[RoundingDirection] -> ShowS
RoundingDirection -> String
(Int -> RoundingDirection -> ShowS)
-> (RoundingDirection -> String)
-> ([RoundingDirection] -> ShowS)
-> Show RoundingDirection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RoundingDirection -> ShowS
showsPrec :: Int -> RoundingDirection -> ShowS
$cshow :: RoundingDirection -> String
show :: RoundingDirection -> String
$cshowList :: [RoundingDirection] -> ShowS
showList :: [RoundingDirection] -> ShowS
Show)

-- | Use the given rounding direction to round the given fractional value,
--   producing an integral result.
--
round :: (RealFrac a, Integral b) => RoundingDirection -> a -> b
round :: forall a b. (RealFrac a, Integral b) => RoundingDirection -> a -> b
round = \case
    RoundingDirection
RoundUp -> a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling
    RoundingDirection
RoundDown -> a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor