module Unison.Prelude
( module X,
readUtf8,
safeReadUtf8,
safeReadUtf8StdIn,
writeUtf8,
prependUtf8,
uncurry4,
reportBug,
tShow,
wundefined,
onFalse,
onFalseM,
onTrue,
onTrueM,
onNothing,
onNothingM,
whenNothing,
whenNothingM,
whenJust,
whenJustM,
eitherToMaybe,
maybeToEither,
altSum,
altMap,
hoistMaybe,
onLeft,
onLeftM,
whenLeft,
whenLeftM,
throwEitherM,
throwEitherMWith,
throwExceptT,
throwExceptTWith,
(^.),
(.~),
(%~),
view,
set,
over,
)
where
import Control.Applicative as X
import Control.Category as X ((>>>))
import Control.Exception as X (Exception, IOException, SomeException)
import Control.Lens (over, set, view, (%~), (.~), (^.))
import Control.Monad as X
import Control.Monad.Extra as X (ifM, mapMaybeM, unlessM, whenM)
import Control.Monad.IO.Class as X (MonadIO (liftIO))
import Control.Monad.Trans as X (MonadTrans (lift))
import Control.Monad.Trans.Except (ExceptT (ExceptT), runExceptT, withExceptT)
import Control.Monad.Trans.Maybe as X (MaybeT (MaybeT, runMaybeT))
import Data.Bifunctor as X (Bifunctor (..))
import Data.ByteString as X (ByteString)
import Data.Coerce as X (Coercible, coerce)
import Data.Either as X
import Data.Either.Combinators as X (mapLeft, maybeToRight)
import Data.Either.Extra (eitherToMaybe, maybeToEither)
import Data.Foldable as X (fold, foldl', for_, toList, traverse_)
import Data.Function as X ((&))
import Data.Functor as X
import Data.Functor.Identity as X
import Data.Generics.Labels ()
import Data.Int as X
import Data.List as X (foldl1', sortOn)
import Data.Map as X (Map)
import Data.Maybe as X (catMaybes, fromMaybe, isJust, isNothing, listToMaybe, maybeToList)
import Data.Sequence as X (Seq)
import Data.Set as X (Set)
import Data.String as X (IsString, fromString)
import Data.Text as X (Text)
import Data.Text qualified as Text
import Data.Text.Encoding as X (decodeUtf8, encodeUtf8)
import Data.Text.IO qualified as Text
import Data.Traversable as X (for)
import Data.Typeable as X (Typeable)
import Data.Void as X (Void)
import Data.Word as X
import Debug.Trace as X
import GHC.Generics as X (Generic, Generic1)
import GHC.IO.Handle qualified as Handle
import GHC.Stack as X (HasCallStack)
import Safe as X (atMay, headMay, lastMay, readMay)
import System.Directory qualified as Directory
import System.FilePath qualified as FilePath
import System.IO qualified as IO
import Text.Read as X (readMaybe)
import UnliftIO as X (MonadUnliftIO (..), askRunInIO, askUnliftIO, try, withUnliftIO)
import UnliftIO qualified
import UnliftIO.Directory qualified as UnliftIO
import Witch as X (From (from), TryFrom (tryFrom), TryFromException (TryFromException), into, tryInto)
import Witherable as X (filterA, forMaybe, mapMaybe, wither, witherMap)
hoistMaybe :: (Applicative m) => Maybe a -> MaybeT m a
hoistMaybe :: forall (m :: * -> *) a. Applicative m => Maybe a -> MaybeT m a
hoistMaybe = m (Maybe a) -> MaybeT m a
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a)
-> (Maybe a -> m (Maybe a)) -> Maybe a -> MaybeT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
altSum :: (Alternative f, Foldable t) => t (f a) -> f a
altSum :: forall (f :: * -> *) (t :: * -> *) a.
(Alternative f, Foldable t) =>
t (f a) -> f a
altSum = (f a -> f a -> f a) -> f a -> t (f a) -> f a
forall b a. (b -> a -> b) -> b -> t a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' f a -> f a -> f a
forall a. f a -> f a -> f a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) f a
forall a. f a
forall (f :: * -> *) a. Alternative f => f a
empty
altMap :: (Alternative f, Foldable t) => (a -> f b) -> t a -> f b
altMap :: forall (f :: * -> *) (t :: * -> *) a b.
(Alternative f, Foldable t) =>
(a -> f b) -> t a -> f b
altMap a -> f b
f = [f b] -> f b
forall (f :: * -> *) (t :: * -> *) a.
(Alternative f, Foldable t) =>
t (f a) -> f a
altSum ([f b] -> f b) -> (t a -> [f b]) -> t a -> f b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> f b) -> [a] -> [f b]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> f b
f ([a] -> [f b]) -> (t a -> [a]) -> t a -> [f b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t a -> [a]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
onFalse :: (Applicative m) => m () -> Bool -> m ()
onFalse :: forall (m :: * -> *). Applicative m => m () -> Bool -> m ()
onFalse m ()
action = \case
Bool
False -> m ()
action
Bool
True -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
onFalseM :: (Monad m) => m () -> m Bool -> m ()
onFalseM :: forall (m :: * -> *). Monad m => m () -> m Bool -> m ()
onFalseM m ()
x m Bool
y =
m Bool
y m Bool -> (Bool -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m () -> Bool -> m ()
forall (m :: * -> *). Applicative m => m () -> Bool -> m ()
onFalse m ()
x
onTrue :: (Applicative m) => m () -> Bool -> m ()
onTrue :: forall (m :: * -> *). Applicative m => m () -> Bool -> m ()
onTrue m ()
action = \case
Bool
True -> m ()
action
Bool
False -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
onTrueM :: (Monad m) => m () -> m Bool -> m ()
onTrueM :: forall (m :: * -> *). Monad m => m () -> m Bool -> m ()
onTrueM m ()
x m Bool
y =
m Bool
y m Bool -> (Bool -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m () -> Bool -> m ()
forall (m :: * -> *). Applicative m => m () -> Bool -> m ()
onTrue m ()
x
onNothing :: (Applicative m) => m a -> Maybe a -> m a
onNothing :: forall (m :: * -> *) a. Applicative m => m a -> Maybe a -> m a
onNothing m a
m Maybe a
may = m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe m a
m a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
may
onNothingM :: (Monad m) => m a -> m (Maybe a) -> m a
onNothingM :: forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
onNothingM =
(m (Maybe a) -> m a -> m a) -> m a -> m (Maybe a) -> m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip m (Maybe a) -> m a -> m a
forall (m :: * -> *) a. Monad m => m (Maybe a) -> m a -> m a
whenNothingM
whenNothing :: (Applicative m) => Maybe a -> m a -> m a
whenNothing :: forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
whenNothing Maybe a
may m a
m = m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe m a
m a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
may
whenNothingM :: (Monad m) => m (Maybe a) -> m a -> m a
whenNothingM :: forall (m :: * -> *) a. Monad m => m (Maybe a) -> m a -> m a
whenNothingM m (Maybe a)
mx m a
my =
m (Maybe a)
mx m (Maybe a) -> (Maybe a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m a -> (a -> m a) -> Maybe a -> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe m a
my a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
whenJust :: (Applicative m) => Maybe a -> (a -> m ()) -> m ()
whenJust :: forall (m :: * -> *) a.
Applicative m =>
Maybe a -> (a -> m ()) -> m ()
whenJust Maybe a
mx a -> m ()
f =
m () -> (a -> m ()) -> Maybe a -> m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) a -> m ()
f Maybe a
mx
whenJustM :: (Monad m) => m (Maybe a) -> (a -> m ()) -> m ()
whenJustM :: forall (m :: * -> *) a.
Monad m =>
m (Maybe a) -> (a -> m ()) -> m ()
whenJustM m (Maybe a)
mx a -> m ()
f = do
m (Maybe a)
mx m (Maybe a) -> (Maybe a -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m () -> (a -> m ()) -> Maybe a -> m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) a -> m ()
f
onLeft :: (Applicative m) => (a -> m b) -> Either a b -> m b
onLeft :: forall (m :: * -> *) a b.
Applicative m =>
(a -> m b) -> Either a b -> m b
onLeft =
(Either a b -> (a -> m b) -> m b)
-> (a -> m b) -> Either a b -> m b
forall a b c. (a -> b -> c) -> b -> a -> c
flip Either a b -> (a -> m b) -> m b
forall (m :: * -> *) a b.
Applicative m =>
Either a b -> (a -> m b) -> m b
whenLeft
onLeftM :: (Monad m) => (a -> m b) -> m (Either a b) -> m b
onLeftM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> m (Either a b) -> m b
onLeftM =
(m (Either a b) -> (a -> m b) -> m b)
-> (a -> m b) -> m (Either a b) -> m b
forall a b c. (a -> b -> c) -> b -> a -> c
flip m (Either a b) -> (a -> m b) -> m b
forall (m :: * -> *) a b.
Monad m =>
m (Either a b) -> (a -> m b) -> m b
whenLeftM
whenLeft :: (Applicative m) => Either a b -> (a -> m b) -> m b
whenLeft :: forall (m :: * -> *) a b.
Applicative m =>
Either a b -> (a -> m b) -> m b
whenLeft = \case
Left a
a -> \a -> m b
f -> a -> m b
f a
a
Right b
b -> \a -> m b
_ -> b -> m b
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
b
whenLeftM :: (Monad m) => m (Either a b) -> (a -> m b) -> m b
whenLeftM :: forall (m :: * -> *) a b.
Monad m =>
m (Either a b) -> (a -> m b) -> m b
whenLeftM m (Either a b)
m a -> m b
f =
m (Either a b)
m m (Either a b) -> (Either a b -> m b) -> m b
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left a
x -> a -> m b
f a
x
Right b
y -> b -> m b
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
y
throwExceptT :: (MonadIO m, Exception e) => ExceptT e m a -> m a
throwExceptT :: forall (m :: * -> *) e a.
(MonadIO m, Exception e) =>
ExceptT e m a -> m a
throwExceptT = (e -> e) -> ExceptT e m a -> m a
forall (m :: * -> *) e' e a.
(MonadIO m, Exception e') =>
(e -> e') -> ExceptT e m a -> m a
throwExceptTWith e -> e
forall a. a -> a
id
throwExceptTWith :: (MonadIO m, Exception e') => (e -> e') -> ExceptT e m a -> m a
throwExceptTWith :: forall (m :: * -> *) e' e a.
(MonadIO m, Exception e') =>
(e -> e') -> ExceptT e m a -> m a
throwExceptTWith e -> e'
f ExceptT e m a
action =
ExceptT e' m a -> m (Either e' a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT ((e -> e') -> ExceptT e m a -> ExceptT e' m a
forall (m :: * -> *) e e' a.
Functor m =>
(e -> e') -> ExceptT e m a -> ExceptT e' m a
withExceptT e -> e'
f ExceptT e m a
action) m (Either e' a) -> (Either e' a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left e'
e -> IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> (e' -> IO a) -> e' -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e' -> IO a
forall (m :: * -> *) e a. (MonadIO m, Exception e) => e -> m a
UnliftIO.throwIO (e' -> m a) -> e' -> m a
forall a b. (a -> b) -> a -> b
$ e'
e
Right a
a -> a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
throwEitherM :: forall e m a. (MonadIO m, Exception e) => m (Either e a) -> m a
throwEitherM :: forall e (m :: * -> *) a.
(MonadIO m, Exception e) =>
m (Either e a) -> m a
throwEitherM = (e -> e) -> m (Either e a) -> m a
forall e e' (m :: * -> *) a.
(MonadIO m, Exception e') =>
(e -> e') -> m (Either e a) -> m a
throwEitherMWith e -> e
forall a. a -> a
id
throwEitherMWith :: forall e e' m a. (MonadIO m, Exception e') => (e -> e') -> m (Either e a) -> m a
throwEitherMWith :: forall e e' (m :: * -> *) a.
(MonadIO m, Exception e') =>
(e -> e') -> m (Either e a) -> m a
throwEitherMWith e -> e'
f m (Either e a)
action = ExceptT e' m a -> m a
forall (m :: * -> *) e a.
(MonadIO m, Exception e) =>
ExceptT e m a -> m a
throwExceptT (ExceptT e' m a -> m a)
-> (ExceptT e m a -> ExceptT e' m a) -> ExceptT e m a -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> e') -> ExceptT e m a -> ExceptT e' m a
forall (m :: * -> *) e e' a.
Functor m =>
(e -> e') -> ExceptT e m a -> ExceptT e' m a
withExceptT e -> e'
f (ExceptT e m a -> m a) -> ExceptT e m a -> m a
forall a b. (a -> b) -> a -> b
$ (m (Either e a) -> ExceptT e m a
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT m (Either e a)
action)
tShow :: (Show a) => a -> Text
tShow :: forall a. Show a => a -> Text
tShow = String -> Text
Text.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
readUtf8 :: FilePath -> IO Text
readUtf8 :: String -> IO Text
readUtf8 String
fileName =
String -> IOMode -> (Handle -> IO Text) -> IO Text
forall (m :: * -> *) a.
MonadUnliftIO m =>
String -> IOMode -> (Handle -> m a) -> m a
UnliftIO.withFile String
fileName IOMode
UnliftIO.ReadMode Handle -> IO Text
readUtf8Handle
safeReadUtf8 :: FilePath -> IO (Either IOException Text)
safeReadUtf8 :: String -> IO (Either IOException Text)
safeReadUtf8 String
p = IO Text -> IO (Either IOException Text)
forall (m :: * -> *) e a.
(MonadUnliftIO m, Exception e) =>
m a -> m (Either e a)
try (String -> IO Text
readUtf8 String
p)
readUtf8Handle :: IO.Handle -> IO Text
readUtf8Handle :: Handle -> IO Text
readUtf8Handle Handle
handle = do
Handle -> TextEncoding -> IO ()
Handle.hSetEncoding Handle
handle TextEncoding
IO.utf8
Handle -> IO Text
Text.hGetContents Handle
handle
safeReadUtf8StdIn :: IO (Either IOException Text)
safeReadUtf8StdIn :: IO (Either IOException Text)
safeReadUtf8StdIn = do
Handle
handle <- Handle -> IO Handle
Handle.hDuplicate Handle
IO.stdin
IO Text -> IO (Either IOException Text)
forall (m :: * -> *) e a.
(MonadUnliftIO m, Exception e) =>
m a -> m (Either e a)
try (IO Text -> IO (Either IOException Text))
-> IO Text -> IO (Either IOException Text)
forall a b. (a -> b) -> a -> b
$ Handle -> IO Text
readUtf8Handle Handle
handle
uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 :: forall a b c d e. (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 a -> b -> c -> d -> e
f (a
a, b
b, c
c, d
d) =
a -> b -> c -> d -> e
f a
a b
b c
c d
d
writeUtf8 :: FilePath -> Text -> IO ()
writeUtf8 :: String -> Text -> IO ()
writeUtf8 String
fileName Text
txt = do
String -> IOMode -> (Handle -> IO ()) -> IO ()
forall (m :: * -> *) a.
MonadUnliftIO m =>
String -> IOMode -> (Handle -> m a) -> m a
UnliftIO.withFile String
fileName IOMode
UnliftIO.WriteMode ((Handle -> IO ()) -> IO ()) -> (Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Handle
handle -> do
Handle -> TextEncoding -> IO ()
Handle.hSetEncoding Handle
handle TextEncoding
IO.utf8
Handle -> Text -> IO ()
Text.hPutStr Handle
handle Text
txt
prependUtf8 :: FilePath -> Text -> IO ()
prependUtf8 :: String -> Text -> IO ()
prependUtf8 String
path Text
txt = do
String -> IO Bool
Directory.doesFileExist String
path IO Bool -> (Bool -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
False -> String -> Text -> IO ()
writeUtf8 String
path Text
txt
Bool
True -> do
let withTempFile :: String -> Handle -> IO ()
withTempFile String
tmpFilePath Handle
tmpHandle = do
Handle -> TextEncoding -> IO ()
Handle.hSetEncoding Handle
tmpHandle TextEncoding
IO.utf8
Handle -> Text -> IO ()
Text.hPutStrLn Handle
tmpHandle Text
txt
String -> IOMode -> (Handle -> IO ()) -> IO ()
forall r. String -> IOMode -> (Handle -> IO r) -> IO r
IO.withFile String
path IOMode
IO.ReadMode \Handle
currentScratchFile -> do
Handle -> TextEncoding -> IO ()
Handle.hSetEncoding Handle
currentScratchFile TextEncoding
IO.utf8
let copyLoop :: IO ()
copyLoop = do
Text
chunk <- Handle -> IO Text
Text.hGetChunk Handle
currentScratchFile
case Text -> Int
Text.length Text
chunk Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 of
Bool
True -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Bool
False -> do
Handle -> Text -> IO ()
Text.hPutStr Handle
tmpHandle Text
chunk
IO ()
copyLoop
IO ()
copyLoop
Handle -> IO ()
IO.hClose Handle
tmpHandle
String -> String -> IO ()
forall (m :: * -> *). MonadIO m => String -> String -> m ()
UnliftIO.renameFile String
tmpFilePath String
path
String -> String -> (String -> Handle -> IO ()) -> IO ()
forall (m :: * -> *) a.
MonadUnliftIO m =>
String -> String -> (String -> Handle -> m a) -> m a
UnliftIO.withTempFile (String -> String
FilePath.takeDirectory String
path) String
".unison-scratch" String -> Handle -> IO ()
withTempFile
reportBug :: String -> String -> String
reportBug :: String -> String -> String
reportBug String
bugId String
msg =
[String] -> String
unlines
[ String
"🐞",
String
"",
String
msg,
String
"",
String
"This is a Unison bug and you can report it here:",
String
"",
String
"https://github.com/unisonweb/unison/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
bugId String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"+",
String
"",
String
"Bug reference: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
bugId,
String
"",
String
"If there's already an issue with this reference, you can give a 👍",
String
"on the issue to let the team know you encountered it, and you can add",
String
"any additional details you know of to the issue."
]
{-# WARNING wundefined "You left this wundefined." #-}
wundefined :: (HasCallStack) => a
wundefined :: forall a. HasCallStack => a
wundefined = a
forall a. HasCallStack => a
undefined