{-# LANGUAGE UndecidableInstances, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts
           , NoMonomorphismRestriction, OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Interlude ( module X, unsafeTail, unsafeHead, unsafeLast, unsafeInit
                 , pshow, perror, pread, noWarnUndefined, perrorToFile ) where

import qualified Prelude
import Protolude as X hiding ( (&), catch, try, (<.>), wait, error, filter, ordNub
                             , catMaybes, mapMaybe, handle, catches, Handler(..) )
import Prelude as X (error)
import Control.Monad.Catch as X ( MonadThrow, MonadCatch, catch, throwM, try, handle, catches
                                , Handler(..), handleIf, catchIf )
import Control.Monad.Trans.Class as X
import Control.Monad.State as X (modify')
import Control.Lens.Operators as X
import Control.Lens.TH as X
import Control.Lens as X (view)
import Data.Aeson.TH as X
import Data.Aeson as X (ToJSON, FromJSON)
import Data.Coerce as X
import Data.Char as X
import Data.Witherable as X
import Data.String
import Control.Monad.Trans.Control as X (MonadBaseControl, MonadTransControl)
import Control.Monad.Random as X
import GHC.IO

import qualified Data.Text as Text

unsafeTail :: [a] -> [a]
unsafeTail = Prelude.tail

unsafeHead :: [a] -> a
unsafeHead = Prelude.head

unsafeLast :: [a] -> a
unsafeLast = Prelude.last

unsafeInit :: [a] -> [a]
unsafeInit = Prelude.init

pshow :: (Show a, IsString c) => a -> c
pshow = fromString . show

perror :: StringConv stringLike String => stringLike -> a
perror = error . toS

pread :: (Read a, StringConv stringLike String) => stringLike -> a
pread = Prelude.read . toS

noWarnUndefined :: a
noWarnUndefined = Prelude.undefined

perrorToFile :: StringConv stringLike Text => Text -> stringLike -> a
perrorToFile path err = unsafePerformIO $ do
    writeFile (toS path) (toS err)
    perror (Text.take 100 (toS err :: Text) <> "...REST OF ERROR IN " <> toS path)