{-# LANGUAGE BangPatterns #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Numeric.Tuple
-- Copyright   :  (c) Artem Chirkin
-- License     :  BSD3
--
--
-----------------------------------------------------------------------------
module Numeric.Tuple
    ( module TS
    , toStrict, fromStrict
    ) where

import qualified Numeric.Tuple.Lazy   as TL
import           Numeric.Tuple.Strict as TS
import           Unsafe.Coerce        (unsafeCoerce)

-- | /O(n)/ Convert a lazy @Tuple@ to a strict @Tuple@, forcing all its values
--   to the WHNF along the way.
toStrict :: TL.Tuple xs -> TS.Tuple xs
toStrict :: Tuple xs -> Tuple xs
toStrict Tuple xs
U = Tuple xs
forall k (f :: k -> *) (xs :: [k]). (xs ~ '[]) => TypedList f xs
U
toStrict (TL.Id y
x :* TypedList Id ys
xs)
  = let !y :: Id y
y = y
x y -> Id y -> Id y
`seq` y -> Id y
forall a. a -> Id a
TS.Id y
x
        !ys :: Tuple ys
ys = TypedList Id ys -> Tuple ys
forall (xs :: [*]). Tuple xs -> Tuple xs
toStrict TypedList Id ys
xs
    in Id y
y Id y -> Tuple ys -> Tuple xs
forall k (f :: k -> *) (xs :: [k]) (y :: k) (ys :: [k]).
(xs ~ (y : ys)) =>
f y -> TypedList f ys -> TypedList f xs
:* Tuple ys
ys

-- | /O(n)/ Convert a strict @Tuple@ to a lazy @Tuple@ by means of a simple coercion.
fromStrict :: TS.Tuple xs -> TL.Tuple xs
fromStrict :: Tuple xs -> Tuple xs
fromStrict = Tuple xs -> Tuple xs
forall a b. a -> b
unsafeCoerce
{-# INLINE fromStrict #-}