diff --git a/quasar.cabal b/quasar.cabal index 1c0f83fbda8c223989a019a0e06a38eb0d884939..a339ef314020b05c12b0ec22fe0bbaf51b662de0 100644 --- a/quasar.cabal +++ b/quasar.cabal @@ -15,6 +15,7 @@ common shared-properties default-extensions: AllowAmbiguousTypes BangPatterns + ConstraintKinds DataKinds DefaultSignatures DeriveAnyClass @@ -33,6 +34,7 @@ common shared-properties NamedFieldPuns NoImplicitPrelude OverloadedStrings + PolyKinds RankNTypes ScopedTypeVariables StandaloneDeriving @@ -48,6 +50,7 @@ common shared-properties hashable, microlens-platform, mtl, + record-hasfield, template-haskell, transformers, unordered-containers, diff --git a/src/Quasar/Prelude.hs b/src/Quasar/Prelude.hs index ada83ca5edf0c3c93bb59cded9febe4dd9a9404d..edcaccf177797faecae877c170434fb4824bba4f 100644 --- a/src/Quasar/Prelude.hs +++ b/src/Quasar/Prelude.hs @@ -1,13 +1,12 @@ -{-# LANGUAGE PackageImports #-} -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE PolyKinds #-} - module Quasar.Prelude - ( module BasePrelude, + ( module Prelude, module Quasar.PreludeExtras, (>=>), (<=<), Control.Applicative.liftA2, + module Control.Concurrent.MVar, + Control.Exception.Exception, + Control.Exception.SomeException, Control.Exception.throwIO, Control.Monad.forever, Control.Monad.unless, @@ -16,15 +15,25 @@ module Quasar.Prelude Control.Monad.forM, Control.Monad.forM_, Control.Monad.join, + Data.Unique.Unique, + Data.Unique.newUnique, Data.Void.Void, Hashable.Hashable, GHC.Generics.Generic, MonadIO, liftIO, - Maybe.catMaybes, - Maybe.fromMaybe, - Maybe.listToMaybe, - Maybe.maybeToList, + Data.Maybe.catMaybes, + Data.Maybe.fromMaybe, + Data.Maybe.listToMaybe, + Data.Maybe.maybeToList, + Data.Int.Int8, + Data.Int.Int16, + Data.Int.Int32, + Data.Int.Int64, + Data.Word.Word8, + Data.Word.Word16, + Data.Word.Word32, + Data.Word.Word64, error, errorWithoutStackTrace, head, @@ -43,26 +52,34 @@ module Quasar.Prelude ) where -import "base" Prelude as BasePrelude hiding +import Prelude hiding ( error, errorWithoutStackTrace, head, last, read, + -- Due to the accepted "monad of no return" proposal, return becomes an + -- alias for pure. Return can be a pitfall for newcomers, so we decided to + -- use pure instead. + return, undefined, ) -import qualified "base" Prelude as P +import qualified Prelude as P import Quasar.PreludeExtras import qualified Control.Applicative +import Control.Concurrent.MVar import qualified Control.Exception import qualified Control.Monad -import qualified Data.Void import Control.Monad ((>=>), (<=<)) import Control.Monad.IO.Class (MonadIO, liftIO) import qualified Data.Hashable as Hashable -import qualified Data.Maybe as Maybe +import qualified Data.Int +import qualified Data.Maybe +import qualified Data.Unique +import qualified Data.Void +import qualified Data.Word import qualified Debug.Trace as Trace import qualified GHC.Generics import qualified GHC.Stack.Types diff --git a/src/Quasar/PreludeExtras.hs b/src/Quasar/PreludeExtras.hs index 377efab622232334e494a76c7934530101a773f1..9489b5af89174e39d7b5a9d50e6368ed258f9b33 100644 --- a/src/Quasar/PreludeExtras.hs +++ b/src/Quasar/PreludeExtras.hs @@ -1,14 +1,12 @@ -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE PackageImports #-} - module Quasar.PreludeExtras where -- Use prelude from `base` to prevent module import cycle. -import "base" Prelude +import Prelude import Quasar.Utils.ExtraT import Control.Applicative (liftA2) +import Control.Concurrent (threadDelay) import Control.Monad.State.Lazy as State import qualified Data.Char as Char import qualified Data.Hashable as Hashable @@ -16,7 +14,10 @@ import qualified Data.HashMap.Strict as HM import qualified Data.HashSet as HS import qualified Data.List as List import qualified Data.Maybe as Maybe +import GHC.Records.Compat (HasField, getField, setField) import qualified GHC.Stack.Types +import GHC.TypeLits (Symbol) +import Lens.Micro.Platform (Lens', lens) impossibleCodePath :: GHC.Stack.Types.HasCallStack => a impossibleCodePath = error "Code path marked as impossible was reached" @@ -51,6 +52,7 @@ leftToMaybe :: Either a b -> Maybe a leftToMaybe (Left x) = Just x leftToMaybe (Right _) = Nothing +-- | Returns all duplicate elements in a list. The order of the produced list is unspecified. duplicates :: forall a. (Eq a, Hashable.Hashable a) => [a] -> [a] duplicates = HS.toList . duplicates' HS.empty where @@ -87,3 +89,19 @@ infixr 6 <<>> dup :: a -> (a, a) dup x = (x, x) + +-- | Enumerate all values of an 'Enum' +enumerate :: (Enum a, Bounded a) => [a] +enumerate = [minBound..maxBound] + +-- | Splits a list using a predicate. The separator is removed. The opposite of `intercalate`. +splitOn :: (a -> Bool) -> [a] -> [[a]] +splitOn p s = case break p s of + (w, []) -> [w] + (w, _:r) -> w : splitOn p r + +fieldLens :: forall (x :: Symbol) r a. HasField x r a => Lens' r a +fieldLens = lens (getField @x) (setField @x) + +sleepForever :: IO a +sleepForever = forever $ threadDelay 1000000000000