diff-loc-0.1.0.0: src/DiffLoc/Unsafe.hs
{-# LANGUAGE
DataKinds,
ScopedTypeVariables,
TypeApplications #-}
-- | Unsafe functions that will throw errors if misused.
module DiffLoc.Unsafe
( -- ** Inverting monoid actions
(.-.)
-- ** Smart constructors for 'IndexFrom'
, indexFrom
, indexFrom0
, indexFrom1
-- ** Smart constructor for 'Offset'
, offset
) where
import Data.Maybe (fromMaybe)
import Data.Proxy (Proxy(..))
import GHC.Stack (HasCallStack)
import GHC.TypeNats (KnownNat, natVal)
import DiffLoc.Shift (Amor(Trans, (.-.?)))
import DiffLoc.Index (IndexFrom, Offset, indexFromM, offsetM)
infixl 6 .-.
-- | An unsafe variant of @('.-.?')@ which throws an exception on @Nothing@.
-- This operator may appear in class laws, imposing an implicit requirement
-- that its operands must be ordered.
(.-.) :: HasCallStack => Amor p => p -> p -> Trans p
i .-. j = fromMaybe (error "undefined vector") (i .-.? j)
-- | Constructor for 'IndexFrom'. The index must be greater than the origin,
-- otherwise an error is raised.
--
-- @
-- origin <= indexFrom i
-- @
indexFrom :: forall n a. (HasCallStack, KnownNat n, Num a, Ord a) => a -> IndexFrom n a
indexFrom i = fromMaybe err (indexFromM i)
where err = error ("IndexFrom must not be less than origin " <> show (natVal @n Proxy))
-- | 'indexFrom' specialized to 0-indexing.
indexFrom0 :: (HasCallStack, Num a, Ord a) => a -> IndexFrom 0 a
indexFrom0 = indexFrom
-- | 'indexFrom' specialized to 1-indexing.
indexFrom1 :: (HasCallStack, Num a, Ord a) => a -> IndexFrom 1 a
indexFrom1 = indexFrom
-- | Construct an 'Offset'. The offset must be nonnegative, otherwise
-- an error is raised.
offset :: (HasCallStack, Num a, Ord a) => a -> Offset a
offset i = fromMaybe (error "Offset must not be negative") (offsetM i)