linear-base-0.1.0: src/Prelude/Linear/Internal.hs
-- | This is a very very simple prelude, which doesn't depend on anything else
-- in the linear-base library (except possibly "Unsafe.Linear").
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Prelude.Linear.Internal where
import qualified Prelude as Prelude
import qualified Unsafe.Linear as Unsafe
import Data.Functor.Identity
-- A note on implementation: to avoid silly mistakes, very easy functions are
-- simply reimplemented here. For harder function, we reuse the Prelude
-- definition and make an unsafe cast.
-- | Beware: @($)@ is not compatible with the standard one because it is
-- higher-order and we don't have multiplicity polymorphism yet.
($) :: (a %1-> b) %1-> a %1-> b
-- XXX: Temporary as `($)` should get its typing rule directly from the type
-- inference mechanism.
($) f x = f x
infixr 0 $
(&) :: a %1-> (a %1-> b) %1-> b
x & f = f x
infixl 1 &
id :: a %1-> a
id x = x
const :: a %1-> b -> a
const x _ = x
asTypeOf :: a %1-> a -> a
asTypeOf = const
-- | @seq x y@ only forces @x@ to head normal form, therefore is not guaranteed
-- to consume @x@ when the resulting computation is consumed. Therefore, @seq@
-- cannot be linear in it's first argument.
seq :: a -> b %1-> b
seq x = Unsafe.toLinear (Prelude.seq x)
($!) :: (a %1-> b) %1-> a %1-> b
($!) f !a = f a
-- | Beware, 'curry' is not compatible with the standard one because it is
-- higher-order and we don't have multiplicity polymorphism yet.
curry :: ((a, b) %1-> c) %1-> a %1-> b %1-> c
curry f x y = f (x, y)
-- | Beware, 'uncurry' is not compatible with the standard one because it is
-- higher-order and we don't have multiplicity polymorphism yet.
uncurry :: (a %1-> b %1-> c) %1-> (a, b) %1-> c
uncurry f (x,y) = f x y
-- | Beware: @(.)@ is not compatible with the standard one because it is
-- higher-order and we don't have multiplicity polymorphism yet.
(.) :: (b %1-> c) %1-> (a %1-> b) %1-> a %1-> c
f . g = \x -> f (g x)
-- XXX: temporary: with multiplicity polymorphism functions expecting a
-- non-linear arrow would allow a linear arrow passed, so this would be
-- redundant
-- | Convenience operator when a higher-order function expects a non-linear
-- arrow but we have a linear arrow.
forget :: (a %1-> b) %1-> a -> b
forget f a = f a
-- XXX: Temporary, until newtype record projections are linear.
runIdentity' :: Identity a %1-> a
runIdentity' (Identity x) = x