{-# LANGUAGE GADTs #-}
{-# LANGUAGE LinearTypes #-}
module Monad.Linear where

import Prelude(Int, (+))

data T where T :: Int -> T
data TM a = TM a

class Monad m where
  return :: a #-> m a
  (>>=) :: m a #-> (a #-> m b) #-> m b

(>>) :: Monad m => m () #-> m b #-> m b
m1 >> m2 = m1 >>= \() -> m2

instance Monad TM where
  return = TM
  TM a >>= f = f a

data Unrestricted a where
  Unrestricted :: a -> Unrestricted a

runTM :: TM (Unrestricted a) -> a
runTM (TM (Unrestricted a)) = a

newT :: TM T
newT = return (T 0)

increaseT :: T #-> TM T
increaseT (T i) = return (T (i+1))

extractT :: T #-> TM (T, Unrestricted Int)
extractT (T i) = return (T i, Unrestricted i)

deleteT :: T #-> TM ()
deleteT (T _) = return ()

