module Swarm.Util.UnitInterval (
UnitInterval,
getValue,
mkInterval,
safeIndex,
) where
import Data.List.NonEmpty (NonEmpty, (!!))
import Prelude hiding ((!!))
newtype UnitInterval a = UnitInterval
{ forall a. UnitInterval a -> a
getValue :: a
}
mkInterval :: (Ord a, Num a) => a -> UnitInterval a
mkInterval :: forall a. (Ord a, Num a) => a -> UnitInterval a
mkInterval = a -> UnitInterval a
forall a. a -> UnitInterval a
UnitInterval (a -> UnitInterval a) -> (a -> a) -> a -> UnitInterval a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. Ord a => a -> a -> a
max a
0 (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. Ord a => a -> a -> a
min a
1
safeIndex ::
RealFrac a =>
UnitInterval a ->
NonEmpty b ->
b
safeIndex :: forall a b. RealFrac a => UnitInterval a -> NonEmpty b -> b
safeIndex (UnitInterval a
alpha) NonEmpty b
xs =
NonEmpty b
xs NonEmpty b -> Int -> b
forall a. HasCallStack => NonEmpty a -> Int -> a
!! a -> Int
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (a
alpha a -> a -> a
forall a. Num a => a -> a -> a
* Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (NonEmpty b -> Int
forall a. NonEmpty a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NonEmpty b
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))