introduction (empty) → 0.0.1.0
raw patch · 15 files changed
+809/−0 lines, 15 filesdep +asyncdep +basedep +bytestring
Dependencies added: async, base, bytestring, containers, deepseq, exceptions, filepath, ghc-prim, lifted-base, monad-control, mtl, path, path-io, safe, stm, string-conv, text, transformers, transformers-base, validity, validity-containers
Files
- LICENSE +22/−0
- introduction.cabal +69/−0
- src/Base.hs +48/−0
- src/Bool.hs +41/−0
- src/Concurrency.hs +11/−0
- src/Debug.hs +52/−0
- src/Either.hs +51/−0
- src/Errors.hs +12/−0
- src/FilePaths.hs +55/−0
- src/Functor.hs +10/−0
- src/IOString.hs +112/−0
- src/Introduction.hs +184/−0
- src/List.hs +60/−0
- src/Monad.hs +43/−0
- src/Unsafe.hs +39/−0
+ LICENSE view
@@ -0,0 +1,22 @@+The MIT License++Copyright (c) 2016 Tom Sydney Kerckhove http://cs-syd.eu++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.+
+ introduction.cabal view
@@ -0,0 +1,69 @@+name: introduction+version: 0.0.1.0+synopsis: A prelude for safe new projects+description: A prelude for safe new projects+homepage: https://github.com/NorfairKing/introduction+license: MIT+license-file: LICENSE+author: Tom Sydney Kerckhove+maintainer: syd.kerckhove@gmail.com+copyright: 2016 Tom Sydney Kerckhove+category: Prelude+build-type: Simple+cabal-version: >=1.10+tested-with:+ GHC == 8.0.1+Bug-Reports: https://github.com/NorfairKing/introduction/issues++library+ hs-source-dirs:+ src++ exposed-modules:+ Introduction+ Unsafe++ other-modules:+ Base+ Bool+ Concurrency+ Debug+ Either+ Errors+ Functor+ IOString+ List+ Monad+ FilePaths++ ghc-options:+ -Wall+ -fwarn-implicit-prelude++ build-depends:+ base >= 4.9 && < 5 + , ghc-prim >= 0.3 && < 0.6 + , async >= 2.1 && < 2.2 + , bytestring >= 0.10 && < 0.11+ , containers >= 0.5 && < 0.6 + , deepseq >= 1.3 && < 1.6 + , exceptions >= 0.8 && < 0.9+ , filepath >= 1.4 && < 1.5+ , lifted-base >= 0.2 && < 0.3+ , monad-control >= 1.0 && < 1.1+ , mtl >= 2.1 && < 2.3 + , path >= 0.5 && < 0.6+ , path-io >= 1.2 && < 1.3+ , safe >= 0.3 && < 0.4 + , stm >= 2.4 && < 2.5 + , string-conv >= 0.1 && < 0.2 + , text >= 1.2 && < 1.3 + , transformers >= 0.4 && < 0.6 + , transformers-base >= 0.4 && < 0.6 + , validity >= 0.3.0.4 && < 0.4+ , validity-containers >= 0.1.0.1 && < 0.2+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/NorfairKing/introduction
+ src/Base.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Unsafe #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE ExplicitNamespaces #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Base+ ( module X+ ) where++import GHC.Num as X+import GHC.Enum as X+import GHC.Real as X+import GHC.Float as X+import GHC.Show as X (+ Show(..)+ )++import GHC.Base as X (+ (++)+ , seq+ , asTypeOf+ , ord+ )++import System.IO as X (+ print+ , putStr+ , putStrLn+ , writeFile+ , readFile+ , appendFile+ )++import GHC.Types as X (+ Bool+ , Char+ , Int+ , Word+ , Ordering+ , IO+ , Coercible+ )++import Data.Kind as X (+ type (*)+ , type Type+ )
+ src/Bool.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Safe #-}++module Bool+ ( whenM+ , unlessM+ , ifM+ , guardM+ , bool+ , (&&&)+ , (|||)+ ) where++import Control.Monad (Monad, MonadPlus, guard, unless, when, (=<<),+ (>>=))+import Data.Bool (Bool, (&&), (||))+import Data.Function (flip)++bool :: a -> a -> Bool -> a+bool f t p = if p then t else f++whenM :: Monad m => m Bool -> m () -> m ()+whenM p m =+ p >>= flip when m++unlessM :: Monad m => m Bool -> m () -> m ()+unlessM p m =+ p >>= flip unless m++ifM :: Monad m => m Bool -> m a -> m a -> m a+ifM p x y = p >>= \b -> if b then x else y++guardM :: MonadPlus m => m Bool -> m ()+guardM f = guard =<< f+++(&&&) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)+f &&& g = \a -> f a && g a++(|||) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)+f ||| g = \a -> f a || g a
+ src/Concurrency.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Concurrency (+ module X+ ) where++import Control.Concurrent.Async as X+import Control.Concurrent.Lifted as X+import Control.Exception.Lifted as X hiding (Handler)+import Control.Monad.STM as X+import Control.Monad.Trans.Control as X
+ src/Debug.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Unsafe #-}++module Debug+ ( undefined+ , error+ , trace+ , traceM+ , traceIO+ , traceShow+ , traceShowM+ , notImplemented+ ) where++import Control.Monad (Monad, return)+import Data.String (String)++import Base as P+import qualified Debug.Trace as T+import qualified GHC.Err as P (error, undefined)++{-# WARNING undefined "'undefined' remains in code" #-}+undefined :: a+undefined = P.undefined++{-# WARNING error "'error' remains in code" #-}+error :: String -> a+error = P.error++{-# WARNING trace "'trace' remains in code" #-}+trace :: String -> a -> a+trace = T.trace++{-# WARNING traceShow "'traceShow' remains in code" #-}+traceShow :: P.Show a => a -> b -> b+traceShow a b = T.trace (P.show a) b++{-# WARNING traceShowM "'traceShowM' remains in code" #-}+traceShowM :: (P.Show a, Monad m) => a -> m ()+traceShowM a = traceM (P.show a)++{-# WARNING traceM "'traceM' remains in code" #-}+traceM :: (Monad m) => String -> m ()+traceM s = T.trace s (return ())++{-# WARNING traceIO "'traceIO' remains in code" #-}+traceIO :: String -> P.IO ()+traceIO = T.traceIO++{-# WARNING notImplemented "'notImplemented' remains in code" #-}+notImplemented :: a+notImplemented = P.error "Not implemented"
+ src/Either.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Safe #-}++module Either+ ( maybeToLeft+ , maybeToRight+ , leftToMaybe+ , rightToMaybe+ , maybeToEither+ , whenIsRight+ , whenIsLeft+ , whenRightDo+ , whenLeftDo+ ) where++import Control.Applicative (Applicative (pure))+import Data.Either (Either (..), either)+import Data.Function (const)+import Data.Maybe (Maybe (..), maybe)+import Data.Monoid (Monoid, mempty)++leftToMaybe :: Either l r -> Maybe l+leftToMaybe = either Just (const Nothing)++rightToMaybe :: Either l r -> Maybe r+rightToMaybe = either (const Nothing) Just++maybeToRight :: l -> Maybe r -> Either l r+maybeToRight l = maybe (Left l) Right++maybeToLeft :: r -> Maybe l -> Either l r+maybeToLeft r = maybe (Right r) Left++maybeToEither :: Monoid b => (a -> b) -> Maybe a -> b+maybeToEither = maybe mempty++whenIsRight :: (Applicative m) => Either l r -> m () -> m ()+whenIsRight (Right _) f = f+whenIsRight (Left _) _ = pure ()++whenIsLeft :: (Applicative m) => Either l r -> m () -> m ()+whenIsLeft (Left _) f = f+whenIsLeft (Right _) _ = pure ()++whenRightDo :: (Applicative m) => Either l r -> (r -> m ()) -> m ()+whenRightDo (Right r) f = f r+whenRightDo (Left _) _ = pure ()++whenLeftDo :: (Applicative m) => Either l r -> (l -> m ()) -> m ()+whenLeftDo (Left l) f = f l+whenLeftDo (Right _) _ = pure ()
+ src/Errors.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE NoImplicitPrelude #-}+module Errors+ ( module X+ , catchM+ ) where++import Control.Monad.Catch as X (Exception (..), MonadCatch,+ MonadThrow (..))+import qualified Control.Monad.Catch as E (catch)++catchM :: (MonadCatch m, Exception e) => m a -> (e -> m a) -> m a+catchM = E.catch
+ src/FilePaths.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+module FilePaths+ ( module X+ ) where++import Data.Bool (not, (&&))+import Data.Eq ((/=), (==))+import Data.List (isInfixOf, null)+import Data.Maybe+import qualified System.FilePath as FilePath++import Data.Validity++import Path as X+import Path.Internal+import Path.IO as X++instance Validity (Path Abs File) where+ isValid p@(Path fp)+ = FilePath.isAbsolute fp+ && not (FilePath.hasTrailingPathSeparator fp)+ && FilePath.isValid fp+ && not (".." `isInfixOf` fp)+ && (parseAbsFile fp == Just p)++instance Validity (Path Rel File) where+ isValid p@(Path fp)+ = FilePath.isRelative fp+ && not (FilePath.hasTrailingPathSeparator fp)+ && FilePath.isValid fp+ && fp /= "."+ && fp /= ".."+ && not (".." `isInfixOf` fp)+ && (parseRelFile fp == Just p)++instance Validity (Path Abs Dir) where+ isValid p@(Path fp)+ = FilePath.isAbsolute fp+ && FilePath.hasTrailingPathSeparator fp+ && FilePath.isValid fp+ && not (".." `isInfixOf` fp)+ && (parseAbsDir fp == Just p)++instance Validity (Path Rel Dir) where+ isValid p@(Path fp)+ = FilePath.isRelative fp+ && FilePath.hasTrailingPathSeparator fp+ && FilePath.isValid fp+ && not (null fp)+ && fp /= "."+ && fp /= ".."+ && not (".." `isInfixOf` fp)+ && (parseRelDir fp == Just p)+
+ src/Functor.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Functor+ ( Functor(..)+ , ($>)+ , (<$>)+ , void+ ) where++import Data.Functor (Functor (..), void, ($>), (<$>))
+ src/IOString.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TypeSynonymInstances #-}++module IOString+ ( IOString+ , writeFile+ , readFile+ , appendFile+ , putStr+ , putStrLn+ , putText+ , putTextLn+ , putLText+ , putLTextLn+ , FilePath+ ) where++import qualified Base++import Data.Function ((.), ($))+import GHC.IO (FilePath)++import Control.Monad.IO.Class (MonadIO, liftIO)+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL++import qualified Data.Text as T+import qualified Data.Text.IO as T++import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.IO as TL++import Path++class IOString s where+ iosWriteFile :: FilePath -> s -> Base.IO ()+ iosReadFile :: FilePath -> Base.IO s+ iosAppendFile :: FilePath -> s -> Base.IO ()+ iosPutStr :: s -> Base.IO ()+ iosPutStrLn :: s -> Base.IO ()++instance IOString T.Text where+ iosWriteFile = T.writeFile+ iosReadFile = T.readFile+ iosAppendFile = T.appendFile+ iosPutStr = T.putStr+ iosPutStrLn = T.putStrLn++instance IOString TL.Text where+ iosWriteFile = TL.writeFile+ iosReadFile = TL.readFile+ iosAppendFile = TL.appendFile+ iosPutStr = TL.putStr+ iosPutStrLn = TL.putStrLn++instance IOString BS.ByteString where+ iosWriteFile = BS.writeFile+ iosReadFile = BS.readFile+ iosAppendFile = BS.appendFile+ iosPutStr = BS.putStr+ iosPutStrLn = BS.putStrLn++instance IOString BL.ByteString where+ iosWriteFile = BL.writeFile+ iosReadFile = BL.readFile+ iosAppendFile = BL.appendFile+ iosPutStr = BL.putStr+ iosPutStrLn = BL.putStrLn++instance IOString [Base.Char] where+ iosWriteFile = Base.writeFile+ iosReadFile = Base.readFile+ iosAppendFile = Base.appendFile+ iosPutStr = Base.putStr+ iosPutStrLn = Base.putStrLn++writeFile :: (IOString s, MonadIO m) => (Path Abs File) -> s -> m ()+writeFile p s = liftIO $ iosWriteFile (toFilePath p) s++readFile :: (IOString s, MonadIO m) => (Path Abs File) -> m s+readFile = liftIO . iosReadFile . toFilePath++appendFile :: (IOString s, MonadIO m) => (Path Abs File) -> s -> m ()+appendFile p s = liftIO $ iosAppendFile (toFilePath p) s++putStr :: (IOString s, MonadIO m) => s -> m ()+putStr = liftIO . iosPutStr++putStrLn :: (IOString s, MonadIO m) => s -> m ()+putStrLn = liftIO . iosPutStrLn++-- For forcing type inference+putText :: MonadIO m => T.Text -> m ()+putText = putStr+{-# SPECIALIZE putText :: T.Text -> Base.IO () #-}++putTextLn :: MonadIO m => T.Text -> m ()+putTextLn = putStrLn+{-# SPECIALIZE putText :: T.Text -> Base.IO () #-}++putLText :: MonadIO m => TL.Text -> m ()+putLText = putStr+{-# SPECIALIZE putLText :: TL.Text -> Base.IO () #-}++putLTextLn :: MonadIO m => TL.Text -> m ()+putLTextLn = putStrLn+{-# SPECIALIZE putLText :: TL.Text -> Base.IO () #-}+++
+ src/Introduction.hs view
@@ -0,0 +1,184 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ExplicitNamespaces #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Trustworthy #-}+{-# OPTIONS_GHC -fno-warn-unused-imports #-}++module Introduction+ ( module X+ , module Base+ , applyN+ , show++ , SText+ , LText+ , SByteString+ , LByteString+ ) where++import Bool as X+import Concurrency as X+import Debug as X+import Either as X+import Errors as X+import FilePaths as X+import Functor as X+import IOString as X+import List as X+import Monad as X++import Base as Base hiding (appendFile, putStr,+ putStrLn, readFile, show,+ writeFile)++import Data.String as X (String)++-- Maybe'ized version of partial functions+import Safe as X (atDef, atMay, foldl1May,+ foldr1May, headDef, headMay,+ initDef, initMay, initSafe,+ lastDef, lastMay, tailDef,+ tailMay, tailSafe)++-- Applicatives+import Control.Applicative as X (Alternative (..),+ Applicative (..), Const (..),+ ZipList (..), liftA, liftA2,+ liftA3, optional, (<**>))++-- Base typeclasses+import Data.Data as X (Data (..))+import Data.Eq as X (Eq (..))+import Data.Foldable as X hiding (foldl1, foldr1)+import Data.Functor.Identity as X+import Data.Monoid as X+import Data.Ord as X+import Data.Traversable as X++import Data.RelativeValidity as X+import Data.Validity as X+import Data.Validity.Containers as X ()++-- Deepseq+import Control.DeepSeq as X (NFData (..), deepseq, force,+ ($!!))++-- Data structures+import Data.List as X (break, cycle, drop, dropWhile,+ filter, group, inits,+ intercalate, intersperse,+ isPrefixOf, iterate, map, map,+ permutations, repeat,+ replicate, reverse, scanl,+ scanr, sort, sortBy, splitAt,+ subsequences, tails, take,+ takeWhile, transpose, unfoldr,+ zip, zipWith)+import Data.Tuple as X++import Data.IntMap as X (IntMap)+import Data.IntSet as X (IntSet)+import Data.Map as X (Map)+import Data.Sequence as X (Seq)+import Data.Set as X (Set)++import Data.Proxy as X (Proxy (..))++import Data.Typeable as X (TypeRep, Typeable, cast, eqT,+ typeRep)++import Data.Type.Coercion as X (Coercion (..), coerceWith)++import Data.Type.Equality as X ((:~:) (..), type (==),+ castWith, gcastWith, sym,+ trans)++import Data.Void as X (Void, absurd, vacuous)++-- Monad transformers+import Control.Monad.State as X (MonadState, State, StateT,+ evalState, evalStateT,+ execState, execStateT, get,+ gets, modify, put, runState,+ runStateT, withState)++import Control.Monad.Reader as X (MonadReader, Reader, ReaderT,+ ask, asks, local, runReader,+ runReaderT)++import Control.Monad.Writer as X (MonadWriter, Writer, WriterT,+ execWriter, execWriterT,+ listen, pass, runWriter,+ runWriterT, tell, writer)++import Control.Monad.Except as X (Except, ExceptT, MonadError,+ catchError, mapExcept,+ mapExceptT, runExcept,+ runExceptT, throwError,+ withExceptT)++import Control.Monad.Base as X (MonadBase)+import Control.Monad.IO.Class as X (MonadIO, liftIO)+import Control.Monad.Trans.Class as X (lift)++-- Base types+import Data.Bits as X+import Data.Bool as X hiding (bool)+import Data.Char as X (chr)+import Data.Complex as X+import Data.Either as X+import Data.Int as X+import Data.Maybe as X hiding (fromJust)+import Data.Word as X++import Data.Function as X (const, fix, flip, id, on, ($),+ (.))++-- Genericss+import GHC.Generics as X (Generic)++-- ByteString+import Data.ByteString as X (ByteString)+import qualified Data.ByteString+import qualified Data.ByteString.Lazy++-- Text+import Data.Text as X (Text)+import qualified Data.Text+import qualified Data.Text.IO+import qualified Data.Text.Lazy+import Text.Show (Show (..))++import Data.Text.Lazy (fromStrict, toStrict)++import Data.String as X (IsString)++-- Printf+import Text.Printf as X (PrintfArg, hPrintf, printf)++-- IO+import System.Exit as X+--import System.Info as X+import System.Environment as X (getArgs)+import System.IO as X (Handle)++-- ST+import Control.Monad.ST as X++import Foreign.Storable as X (Storable)++-- Read instances hiding unsafe builtins (read)+import Text.Read as X (Read, readEither, readMaybe,+ reads)++-- Type synonymss+type SText = Data.Text.Text+type LText = Data.Text.Lazy.Text++type SByteString = Data.ByteString.ByteString+type LByteString = Data.ByteString.Lazy.ByteString++applyN :: Int -> (a -> a) -> a -> a+applyN n f = X.foldr (.) id (X.replicate n f)
+ src/List.hs view
@@ -0,0 +1,60 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Safe #-}++module List+ ( ordNub+ , sortOn+ , uncons+ , snoc+ , windows+ , chunksOf+ ) where++import Data.Bool (otherwise)+import Data.Function ((.))+import Data.Int (Int)+import Data.List (drop, length, sortBy, take, (++))+import Data.Maybe (Maybe (..))+import Data.Ord (Ord (..), comparing)+import qualified Data.Set as Set++sortOn :: (Ord o) => (a -> o) -> [a] -> [a]+sortOn = sortBy . comparing++-- | Fast @nub@ if the contents of the list are orderable+--+-- O(n * log n)+ordNub :: (Ord a) => [a] -> [a]+ordNub l = go Set.empty l+ where+ go _ [] = []+ go s (x:xs) =+ if x `Set.member` s+ then go s xs+ else x : go (Set.insert x s) xs++-- | Deconstruct a list into its first element the rest of the list+-- This will evaluate to @Nothing@ if the list is empty.+uncons :: [a] -> Maybe (a, [a])+uncons [] = Nothing+uncons (x:xs) = Just (x, xs)++-- | @(:)@, appending instead of prepending+-- @(:)@ is sometimes called cons, so when we append instead of prepend, we call the function @snoc@+-- Note that this has an O(length list) time complexity+snoc :: [a] -> a -> [a]+snoc as a = as ++ [a]++-- | Find all @i@-sized windows in a list+windows :: Int -> [a] -> [[a]]+windows _ [] = []+windows i xss@(_:xs)+ | length xss >= i = (take i xss) : windows i xs+ | otherwise = []++-- | Takes chunks of a given size, the last chunk may be smaller but not empty.+chunksOf :: Int -> [a] -> [[a]]+chunksOf _ [] = []+chunksOf i xs+ | length xs >= i = take i xs : chunksOf i (drop i xs)+ | otherwise = [xs]
+ src/Monad.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Safe #-}++module Monad (+ Monad((>>=), return)+ , MonadPlus(..)++ , (=<<)+ , (>=>)+ , (<=<)+ , forever++ , join+ , mfilter+ , filterM+ , mapAndUnzipM+ , zipWithM+ , zipWithM_+ , foldM+ , foldM_+ , replicateM+ , replicateM_+ , concatMapM++ , guard+ , when+ , unless++ , liftM+ , liftM2+ , liftM3+ , liftM4+ , liftM5+ , ap+ ) where++import Data.List (concat)++import Control.Monad hiding ((<$!>))++concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]+concatMapM f xs = liftM concat (mapM f xs)
+ src/Unsafe.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE Unsafe #-}++module Unsafe (+ unsafeHead,+ unsafeTail,+ unsafeInit,+ unsafeLast,+ unsafeFromJust,+ unsafeIndex,+) where++import Base (Int)+import qualified Data.List as List+import qualified Data.Maybe as Maybe++{-# WARNING unsafeHead "An unsafe function: 'unsafehead' remains in code" #-}+unsafeHead :: [a] -> a+unsafeHead = List.head++{-# WARNING unsafeTail "An unsafe function: 'unsafeTail' remains in code" #-}+unsafeTail :: [a] -> [a]+unsafeTail = List.tail++{-# WARNING unsafeInit "An unsafe function: 'unsafeInit' remains in code" #-}+unsafeInit :: [a] -> [a]+unsafeInit = List.init++{-# WARNING unsafeLast "An unsafe function: 'unsafeLast' remains in code" #-}+unsafeLast :: [a] -> a+unsafeLast = List.last++{-# WARNING unsafeFromJust "An unsafe function: 'unsafeFromJust' remains in code" #-}+unsafeFromJust :: Maybe.Maybe a -> a+unsafeFromJust = Maybe.fromJust++{-# WARNING unsafeIndex "An unsafe function: 'unsafeIndex' remains in code" #-}+unsafeIndex :: [a] -> Int -> a+unsafeIndex = (List.!!)