coordinate-0.0.10: src/Data/Geo/Coordinate/Minutes.hs
{-# LANGUAGE NoImplicitPrelude #-}
module Data.Geo.Coordinate.Minutes(
Minutes
, HasMinutes(..)
, nMinutes
, modMinutes
) where
import Control.Category(Category(id))
import Control.Lens(Prism', Lens', prism')
import Data.Bool((&&))
import Data.Maybe(Maybe(Just, Nothing))
import Data.Eq(Eq)
import Data.Int(Int)
import Data.Fixed(mod')
import Data.Ord(Ord((>=), (<)))
import Prelude(Show)
-- $setup
-- >>> import Control.Lens((#), (^?))
-- >>> import Data.Foldable(all)
-- >>> import Prelude(Eq(..))
newtype Minutes =
Minutes Int
deriving (Eq, Ord, Show)
-- | Construct minutes such that if the given value is out of bounds,
-- a modulus is taken to keep it within 0 inclusive and 59 inclusive.
--
-- >>> modMinutes 7
-- Minutes 7
--
-- >>> modMinutes 0
-- Minutes 0
--
-- >>> modMinutes 60
-- Minutes 0
--
-- >>> modMinutes 61
-- Minutes 1
--
-- >>> modMinutes 59
-- Minutes 59
modMinutes ::
Int
-> Minutes
modMinutes x =
Minutes (x `mod'` 60)
-- | A prism on minutes to an integer between 0 and 59 inclusive.
--
-- >>> 7 ^? nMinutes
-- Just (Minutes 7)
--
-- >>> 0 ^? nMinutes
-- Just (Minutes 0)
--
-- >>> 59 ^? nMinutes
-- Just (Minutes 59)
--
-- >>> 60 ^? nMinutes
-- Nothing
--
-- prop> all (\m -> nMinutes # m == n) (n ^? nMinutes)
nMinutes ::
Prism' Int Minutes
nMinutes =
prism'
(\(Minutes i) -> i)
(\i -> if i >= 0 && i < 60
then Just (Minutes i)
else Nothing)
class HasMinutes t where
minutes ::
Lens' t Minutes
instance HasMinutes Minutes where
minutes =
id