fpco / unliftio Goto Github PK
View Code? Open in Web Editor NEWThe MonadUnliftIO typeclass for unlifting monads to IO
License: Other
The MonadUnliftIO typeclass for unlifting monads to IO
License: Other
The definitions for Handler
in both of these libraries appear to be the same.
-- | Generalized version of 'ControlException.Handler'
data Handler m a = forall e . ControlException.Exception e => Handler (e -> m a)
-- | A helper data type for usage with 'catches' and similar functions.
--
-- @since 0.1.0.0
data Handler m a = forall e . Exception e => Handler (e -> m a)
This would require depending on exceptions
, or an as-of-yet-unreleased package that factors the generalized Handler
out.
Let me keep discussion around the RIO
monad aproach.
I've already used monad RIO
a lot in my commercial GUI application that is based on sdl2
and reactive-banana
libraries and targets to Windows-Linux desktops and ARM embedded; it must be fast, responsive and robust as it works 24/7 on this sensor stand.
At now I use the following module:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module UnliftIO.MonadRIO where
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Reader (MonadReader, ReaderT (ReaderT))
import Control.Monad.Trans.Resource (MonadResource, liftResourceT, MonadThrow, ResourceT,
InternalState, runInternalState, withInternalState)
import Control.Monad.Base (MonadBase)
import Control.Lens (Lens', view)
import UnliftIO (MonadUnliftIO)
newtype RIO env a = RIO { unRIO :: ReaderT env IO a }
deriving (Functor, Applicative, Monad, MonadIO, MonadReader env,
MonadThrow, MonadBase IO, MonadUnliftIO)
{-# INLINE runRIO #-}
runRIO :: MonadIO m => env -> RIO env a -> m a
runRIO env (RIO (ReaderT f)) = liftIO (f env)
instance HasResources env => MonadResource (RIO env) where
{-# INLINE liftResourceT #-}
liftResourceT resT = view resourcesL >>= liftIO . runResources resT
newtype Resources = Resources InternalState
{-# INLINE runResources #-}
runResources :: ResourceT m a -> Resources -> m a
runResources action (Resources intState) = runInternalState action intState
{-# INLINE withResources #-}
withResources :: (Resources -> m a) -> ResourceT m a
withResources action = withInternalState (action . Resources)
class HasResources env where
resourcesL :: Lens' env Resources
instance HasResources Resources where
{-# INLINE resourcesL #-}
resourcesL = id
UnliftIO.Exception
gives me capabilities of safe-exceptions
and lifted-base
, UnliftIO.Async
gives safe lifted async
; also I've added #5 to get almost full (and in the same time safer) strength of lifted-base
.
In this issue I want to discuss
RIO
monad to unliftio-core
or unliftio
or anywhere else;RIO
monad with ResourceT
- at now I use lens
and instance HasResources env => MonadResource (RIO env)
;monad-logger
.The mostly great overview documentation for the unliftio
library waits until page 7 to mention that the library changes the semantics of async exceptions. Since the main unlifting concept is easy to understand from the examples, and is orthogonal to changing async exception semantics, I expect many people don't read all the way to the end and never imagine the library would also change async semantics. Some of those people (me) will then spend hours debugging subtle problems related to the changed async exception semantics. I propose that the documentation make it loud and clear, from the beginning, that the library changes async exception semantics and is not simply a drop in generalization of Control.Exception
when it comes to exceptions.
The "Quickstart" on the first page of the docs does say "Replace imports like Control.Exception with UnliftIO.Exception. Yay, your catch and finally are more powerful and safer!", with "safer" here hinting at the changed semantics, but I don't think that's going to help anyone who doesn't already know that unliftio
takes the safe-exceptions
approach. In fact, the docs even give an example of implementing an unliftio
version of mask
, which is one of the exception-related functions that does not change async semantics, encouraging further confusion.
Because the unlifting is orthogonal to the safe exceptions, I suppose the best approach would be to make the safe exceptions opt-in, by making two versions of the library, say unliftio-traditional-exceptions
and unliftio-safe-exceptions
; might be a nice use for backpack when it's mature.
I guess unliftio goal is to rexexport System.Directory functions with lifted IO monad.
I noticed that createFileLink is not provided.
Is it exported from other place? IMHO the function name doesn't fit well into the origin namespace, does it?
timeout
and race
use async exceptions to cancel a timed-out action. IMO, the fact that these use async exceptions are an implementation detail, so I would think the user shouldn't have to care about the fact that these use async exceptions.
For example, if someone were to do
action `finally` timeout (60 * 1000000) cleanup
I think the user would be surprised that it doesn't timeout.
Building a project that includes unliftio
(Stackage LTS 14.27 i.e. GHC 8.6.5) fails with this:
unliftio > [20 of 20] Compiling UnliftIO
unliftio >
unliftio > /private/var/folders/n0/zx3dkw3d2hd3x59rjk3gtj5r0000gn/T/stack24793/unliftio-0.2.12/cbits/file-posix.c:16:10: error:
unliftio > error: use of undeclared identifier 'AT_FDCWD'
unliftio > return AT_FDCWD;
unliftio > ^
unliftio > |
unliftio > 16 | return AT_FDCWD;
unliftio > | ^
unliftio >
unliftio > /private/var/folders/n0/zx3dkw3d2hd3x59rjk3gtj5r0000gn/T/stack24793/unliftio-0.2.12/cbits/file-posix.c:21:10: error:
unliftio > error: use of undeclared identifier 'AT_SYMLINK_FOLLOW'
unliftio > return AT_SYMLINK_FOLLOW;
unliftio > ^
unliftio > |
unliftio > 21 | return AT_SYMLINK_FOLLOW;
unliftio > | ^
unliftio > 2 errors generated.
unliftio > `gcc' failed in phase `C Compiler'. (Exit code: 1)
If it helps,
$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix
https://hackage.haskell.org/package/transformers-0.6.0.0/changelog
Could you upload a compatible release of unliftio-core
or make a Hackage revision? Thanks!
This is a bit of a weird one... apologies that I can't provide more information.
I'm seeing hangs in withSystemTempDirectory
where the CPU remains pegged at 100%.
Unfortunately, I haven't been able to reproduce using a small program, so if possible I'd like advice on how to debug further.
I've got an strace snippet from the call to withSystemTempDirectory
:
stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=760, ...}) = 0
lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=760, ...}) = 0
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]}) = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]}) = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]}) = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]}) = 1
--- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=NULL}} ---
rt_sigreturn({mask=[]}) = 1
[...]
timer_settime(0, 0, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=0, tv_nsec=0}}, NULL) = 0
rt_sigreturn({mask=[]}) = 1
AFAICT the SIGVTALRM stuff is from the GHC RTS and not really related to withSystemTempDirecotry
.
Any ideas on how to get more debug info that could be of use tracking this down? The problem doesn't reproduce when I try a trivial "main".
(Aside: Would it not be better to use a random number instead of the PID when choosing candidate file names? Given the current implementation a machine-local DoS would be pretty trivial.)
When I do
withBinaryFileDurableAtomic "myfile" WriteMode $ \handle -> do
fd <- handleToFd handle
fm <- Posix.fileMode <$> Posix.getFdStatus fd
Posix.setFdMode fd myPermissionsHere
return x
then myPermissionsHere
results in an fchmod()
, but those permissions are later overridden by an fchmod()
that unliftio does just before the file is closed.
withBinaryFileDurableAtomic
does
mFileMode <- copyFileHandle iomode filePath tmpFileHandle
res <- action tmpFileHandle
atomicDurableTempFileRename dirFd mFileMode tmpFileHandle mTmpFilePath filePath
where mFileMode = Nothing
when copyFileHandle
says that the file doesn't already exist (the normal case), and atomicDurableTempFileRename
runs this:
let fileMode = fromMaybe Posix.stdFileMode mFileMode
-- work around for the glibc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17523
Posix.setFdMode fd fileMode
This means that atomicDurableTempFileRename
will always call setFdMode
with stdFileMode
, thus erasing any permissions the user may have set in action
.
We should call our setFdMode
before res <- action tmpFileHandle
is run.
CC @lehins
Would you consider adding support for async-pool
?
(PS: I've asked a similar question at jwiegley/async-pool#18
Control.Exception
has a mapException
function that can convert exceptions in impure contexts, but not for exceptions thrown in a monadic context:
{-# LANGUAGE DeriveAnyClass #-}
data Exception1 = Exception1 deriving (Show, Exception)
data Exception2 = Exception2 deriving (Show, Exception)
mapException (\Exception1 -> Exception2) (throwIO Exception1)
returns Exception1
. It would be great if unliftio
could provide a helper that would convert exceptions in a monadic context, maybe something like
mapExceptionIO :: (MonadUnliftIO m, Exception e1, Exception e2) => (e1 -> e2) -> m a -> m a
mapExceptionIO f = handle (throwIO . f)
building '/nix/store/c5yfj9bg2qysqvz255v14mkvsrh98k29-unliftio-0.2.19.drv'...
setupCompilerEnvironmentPhase
Build with /nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6.
unpacking sources
unpacking source archive /nix/store/a7f2grmk9qa5qdbg288abw85r4wffn02-unliftio-0.2.19.tar.gz
source root is unliftio-0.2.19
setting SOURCE_DATE_EPOCH to timestamp 1626799065 of file unliftio-0.2.19/unliftio.cabal
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/private/tmp/nix-build-unliftio-0.2.19.drv-0/setup-package.conf.d -j4 -threaded -rtsopts
[1 of 1] Compiling Main ( Setup.hs, /private/tmp/nix-build-unliftio-0.2.19.drv-0/Main.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
Linking Setup ...
updateAutotoolsGnuConfigScriptsPhase
configuring
configureFlags: --verbose --prefix=/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19 --libdir=$prefix/lib/$compiler --libsubdir=$abi/$libname --docdir=/nix/store/bgi1j8418dcg24blq0c0aspks90prxhg-unliftio-0.2.19-doc/share/doc/unliftio-0.2.19 --with-gcc=clang --package-db=/private/tmp/nix-build-unliftio-0.2.19.drv-0/package.conf.d --ghc-options=-j4 --disable-split-objs --disable-library-profiling --disable-profiling --enable-shared --disable-coverage --enable-static --disable-executable-dynamic --enable-tests --disable-benchmarks --enable-library-vanilla --disable-library-for-ghci --extra-include-dirs=/nix/store/bsimh33mww300hcm1rj106ci02g0yvrd-libcxx-11.1.0-dev/include --extra-lib-dirs=/nix/store/f5nirjav817bv6wrqdqrxvy6g0ffs1vp-libcxx-11.1.0/lib --extra-include-dirs=/nix/store/303904q0nr7mv5qrdgmacd9hy5ws6c20-libcxxabi-11.1.0-dev/include --extra-lib-dirs=/nix/store/q65iy5a3jz4g10igwd0fch381cy37bb5-libcxxabi-11.1.0/lib --extra-lib-dirs=/nix/store/mz7i1ga12cb9zfpc29mq0782cfi449qf-compiler-rt-libc-11.1.0/lib --extra-lib-dirs=/nix/store/1998f6nswbff17vc97w62dvv8b131dak-ncurses-6.2/lib --extra-lib-dirs=/nix/store/mi7r8azivrjpi8m0yr84bbv6iip6702x-libffi-3.4.2/lib --extra-lib-dirs=/nix/store/zrj85hlkkfc3ifw87rvmmp15h83rayf2-gmp-6.2.1/lib --extra-include-dirs=/nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/include --extra-lib-dirs=/nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib --extra-framework-dirs=/nix/store/z54k7h2y1hcshfvgzb86lvb62s9x85nd-apple-framework-CoreFoundation-11.0.0/Library/Frameworks --extra-include-dirs=/nix/store/wxjwrich12j8zd7j33vr2zgk0c2y4mhy-libobjc-11.0.0/include --extra-lib-dirs=/nix/store/wxjwrich12j8zd7j33vr2zgk0c2y4mhy-libobjc-11.0.0/lib
Using Parsec parser
Configuring unliftio-0.2.19...
Dependency async >2.1.1: using async-2.2.3
Dependency base >=4.9 && <5: using base-4.14.3.0
Dependency bytestring -any: using bytestring-0.10.12.0
Dependency deepseq -any: using deepseq-1.4.4.0
Dependency directory -any: using directory-1.3.6.0
Dependency filepath -any: using filepath-1.4.2.1
Dependency process >=1.2.0.0: using process-1.6.13.2
Dependency stm >=2.4.3: using stm-2.5.0.1
Dependency time -any: using time-1.9.3
Dependency transformers -any: using transformers-0.5.6.2
Dependency unix -any: using unix-2.7.2.2
Dependency unliftio-core >=0.1.1.0: using unliftio-core-0.2.0.1
Dependency QuickCheck -any: using QuickCheck-2.14.2
Dependency async >2.1.1: using async-2.2.3
Dependency base >=4.9 && <5: using base-4.14.3.0
Dependency bytestring -any: using bytestring-0.10.12.0
Dependency containers -any: using containers-0.6.5.1
Dependency deepseq -any: using deepseq-1.4.4.0
Dependency directory -any: using directory-1.3.6.0
Dependency filepath -any: using filepath-1.4.2.1
Dependency hspec -any: using hspec-2.7.10
Dependency process >=1.2.0.0: using process-1.6.13.2
Dependency stm >=2.4.3: using stm-2.5.0.1
Dependency time -any: using time-1.9.3
Dependency transformers -any: using transformers-0.5.6.2
Dependency unix -any: using unix-2.7.2.2
Dependency unliftio -any: using unliftio-0.2.19
Dependency unliftio-core >=0.1.1.0: using unliftio-core-0.2.0.1
Source component graph:
component lib
component test:unliftio-spec dependency lib
Configured component graph:
component unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
include base-4.14.3.0
include bytestring-0.10.12.0
include deepseq-1.4.4.0
include directory-1.3.6.0
include filepath-1.4.2.1
include process-1.6.13.2
include stm-2.5.0.1
include time-1.9.3
include transformers-0.5.6.2
include unix-2.7.2.2
include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
component unliftio-0.2.19-9MG3WeQy3rNKT6wdGpsYAh-unliftio-spec
include QuickCheck-2.14.2-JCXxcu6guWY7rTDq31xrNV
include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
include base-4.14.3.0
include bytestring-0.10.12.0
include containers-0.6.5.1
include deepseq-1.4.4.0
include directory-1.3.6.0
include filepath-1.4.2.1
include hspec-2.7.10-9kZZjX0DQR793Uvv1TKEpm
include process-1.6.13.2
include stm-2.5.0.1
include time-1.9.3
include transformers-0.5.6.2
include unix-2.7.2.2
include unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
Linked component graph:
unit unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
include base-4.14.3.0
include bytestring-0.10.12.0
include deepseq-1.4.4.0
include directory-1.3.6.0
include filepath-1.4.2.1
include process-1.6.13.2
include stm-2.5.0.1
include time-1.9.3
include transformers-0.5.6.2
include unix-2.7.2.2
include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
UnliftIO=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO,UnliftIO.Async=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Async,UnliftIO.Chan=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Chan,UnliftIO.Concurrent=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Concurrent,UnliftIO.Directory=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Directory,UnliftIO.Environment=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Environment,UnliftIO.Exception=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Exception,UnliftIO.Foreign=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Foreign,UnliftIO.IO=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.IO,UnliftIO.IO.File=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.IO.File,UnliftIO.IORef=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.IORef,UnliftIO.Internals.Async=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Internals.Async,UnliftIO.MVar=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.MVar,UnliftIO.Memoize=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Memoize,UnliftIO.Process=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Process,UnliftIO.QSem=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.QSem,UnliftIO.QSemN=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.QSemN,UnliftIO.STM=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.STM,UnliftIO.Temporary=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Temporary,UnliftIO.Timeout=unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49:UnliftIO.Timeout
unit unliftio-0.2.19-9MG3WeQy3rNKT6wdGpsYAh-unliftio-spec
include QuickCheck-2.14.2-JCXxcu6guWY7rTDq31xrNV
include async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
include base-4.14.3.0
include bytestring-0.10.12.0
include containers-0.6.5.1
include deepseq-1.4.4.0
include directory-1.3.6.0
include filepath-1.4.2.1
include hspec-2.7.10-9kZZjX0DQR793Uvv1TKEpm
include process-1.6.13.2
include stm-2.5.0.1
include time-1.9.3
include transformers-0.5.6.2
include unix-2.7.2.2
include unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
include unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
Ready component graph:
definite unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
depends async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
depends base-4.14.3.0
depends bytestring-0.10.12.0
depends deepseq-1.4.4.0
depends directory-1.3.6.0
depends filepath-1.4.2.1
depends process-1.6.13.2
depends stm-2.5.0.1
depends time-1.9.3
depends transformers-0.5.6.2
depends unix-2.7.2.2
depends unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
definite unliftio-0.2.19-9MG3WeQy3rNKT6wdGpsYAh-unliftio-spec
depends QuickCheck-2.14.2-JCXxcu6guWY7rTDq31xrNV
depends async-2.2.3-DsEJ4nbFYNW2Mz4R8WNmqy
depends base-4.14.3.0
depends bytestring-0.10.12.0
depends containers-0.6.5.1
depends deepseq-1.4.4.0
depends directory-1.3.6.0
depends filepath-1.4.2.1
depends hspec-2.7.10-9kZZjX0DQR793Uvv1TKEpm
depends process-1.6.13.2
depends stm-2.5.0.1
depends time-1.9.3
depends transformers-0.5.6.2
depends unix-2.7.2.2
depends unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
depends unliftio-core-0.2.0.1-Hy41KxS3ore3s5ACrFOvp6
Using Cabal-3.2.1.0 compiled by ghc-8.10
Using compiler: ghc-8.10.6
Using install prefix:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19
Executables installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/bin
Libraries installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/lib/ghc-8.10.6/aarch64-osx-ghc-8.10.6/unliftio-0.2.19-KPzneVgcK915ZIkxxTIj49
Dynamic Libraries installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/lib/ghc-8.10.6/aarch64-osx-ghc-8.10.6
Private executables installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/libexec/aarch64-osx-ghc-8.10.6/unliftio-0.2.19
Data files installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/share/aarch64-osx-ghc-8.10.6/unliftio-0.2.19
Documentation installed in:
/nix/store/bgi1j8418dcg24blq0c0aspks90prxhg-unliftio-0.2.19-doc/share/doc/unliftio-0.2.19
Configuration files installed in:
/nix/store/grfzwk2x8d421xhd0q9fznixzmg89lz4-unliftio-0.2.19/etc
No alex found
Using ar found on system at:
/nix/store/fn10hhcprz2sjfx0ps5657k24kb7inj8-cctools-binutils-darwin-949.0.1/bin/ar
No c2hs found
No cpphs found
No doctest found
Using gcc version 11.1.0 given by user at:
/nix/store/id1jfmdc8h3xrxvbz8rhsab7jpwd4y45-clang-wrapper-11.1.0/bin/clang
Using ghc version 8.10.6 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/ghc
Using ghc-pkg version 8.10.6 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/ghc-pkg
No ghcjs found
No ghcjs-pkg found
No greencard found
Using haddock version 2.24.2 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/haddock
No happy found
Using haskell-suite found on system at: haskell-suite-dummy-location
Using haskell-suite-pkg found on system at: haskell-suite-pkg-dummy-location
No hmake found
Using hpc version 0.68 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/hpc
Using hsc2hs version 0.68.7 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/hsc2hs
Using hscolour version 1.24 found on system at:
/nix/store/ab3k6kf3j5sbmwjgvkgiaj29sxz7nsrx-hscolour-1.24.4/bin/HsColour
No jhc found
Using ld found on system at:
/nix/store/4jbmi4qkwa0g0316ri73iw8ksc4pl150-cctools-binutils-darwin-wrapper-949.0.1/bin/ld
No pkg-config found
Using runghc version 8.10.6 found on system at:
/nix/store/m7njrg10v1mn89mqmjlwpdks9f9w3n2g-ghc-8.10.6/bin/runghc
Using strip found on system at:
/nix/store/id1jfmdc8h3xrxvbz8rhsab7jpwd4y45-clang-wrapper-11.1.0/bin/strip
Using tar found on system at:
/nix/store/2rkvd2ddbs89xhfhjcac7yi9mjf9ra2p-gnutar-1.34/bin/tar
No uhc found
building
Preprocessing library for unliftio-0.2.19..
Building library for unliftio-0.2.19..
[ 1 of 22] Compiling Paths_unliftio ( dist/build/autogen/Paths_unliftio.hs, dist/build/Paths_unliftio.o, dist/build/Paths_unliftio.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 2 of 22] Compiling UnliftIO.Chan ( src/UnliftIO/Chan.hs, dist/build/UnliftIO/Chan.o, dist/build/UnliftIO/Chan.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 3 of 22] Compiling UnliftIO.Directory ( src/UnliftIO/Directory.hs, dist/build/UnliftIO/Directory.o, dist/build/UnliftIO/Directory.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 4 of 22] Compiling UnliftIO.Environment ( src/UnliftIO/Environment.hs, dist/build/UnliftIO/Environment.o, dist/build/UnliftIO/Environment.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 5 of 22] Compiling UnliftIO.Exception ( src/UnliftIO/Exception.hs, dist/build/UnliftIO/Exception.o, dist/build/UnliftIO/Exception.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 6 of 22] Compiling UnliftIO.Foreign ( src/UnliftIO/Foreign.hs, dist/build/UnliftIO/Foreign.o, dist/build/UnliftIO/Foreign.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 7 of 22] Compiling UnliftIO.IO ( src/UnliftIO/IO.hs, dist/build/UnliftIO/IO.o, dist/build/UnliftIO/IO.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
[ 8 of 22] Compiling UnliftIO.IORef ( src/UnliftIO/IORef.hs, dist/build/UnliftIO/IORef.o, dist/build/UnliftIO/IORef.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[ 9 of 22] Compiling UnliftIO.Internals.Async ( src/UnliftIO/Internals/Async.hs, dist/build/UnliftIO/Internals/Async.o, dist/build/UnliftIO/Internals/Async.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[10 of 22] Compiling UnliftIO.Async ( src/UnliftIO/Async.hs, dist/build/UnliftIO/Async.o, dist/build/UnliftIO/Async.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[11 of 22] Compiling UnliftIO.MVar ( src/UnliftIO/MVar.hs, dist/build/UnliftIO/MVar.o, dist/build/UnliftIO/MVar.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[12 of 22] Compiling UnliftIO.IO.File.Posix ( src/UnliftIO/IO/File/Posix.hs, dist/build/UnliftIO/IO/File/Posix.o, dist/build/UnliftIO/IO/File/Posix.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
ld: warning: /nix/store/imir2phxjscnyw7mnxzlv41wn9mhcw4j-libiconv-50/lib/libiconv.dylib, ignoring unexpected dylib file
[13 of 22] Compiling UnliftIO.IO.File ( src/UnliftIO/IO/File.hs, dist/build/UnliftIO/IO/File.o, dist/build/UnliftIO/IO/File.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[14 of 22] Compiling UnliftIO.Concurrent ( src/UnliftIO/Concurrent.hs, dist/build/UnliftIO/Concurrent.o, dist/build/UnliftIO/Concurrent.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[15 of 22] Compiling UnliftIO.Memoize ( src/UnliftIO/Memoize.hs, dist/build/UnliftIO/Memoize.o, dist/build/UnliftIO/Memoize.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[16 of 22] Compiling UnliftIO.Process ( src/UnliftIO/Process.hs, dist/build/UnliftIO/Process.o, dist/build/UnliftIO/Process.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[17 of 22] Compiling UnliftIO.QSem ( src/UnliftIO/QSem.hs, dist/build/UnliftIO/QSem.o, dist/build/UnliftIO/QSem.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[18 of 22] Compiling UnliftIO.QSemN ( src/UnliftIO/QSemN.hs, dist/build/UnliftIO/QSemN.o, dist/build/UnliftIO/QSemN.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[19 of 22] Compiling UnliftIO.STM ( src/UnliftIO/STM.hs, dist/build/UnliftIO/STM.o, dist/build/UnliftIO/STM.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[20 of 22] Compiling UnliftIO.Temporary ( src/UnliftIO/Temporary.hs, dist/build/UnliftIO/Temporary.o, dist/build/UnliftIO/Temporary.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[21 of 22] Compiling UnliftIO.Timeout ( src/UnliftIO/Timeout.hs, dist/build/UnliftIO/Timeout.o, dist/build/UnliftIO/Timeout.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[22 of 22] Compiling UnliftIO ( src/UnliftIO.hs, dist/build/UnliftIO.o, dist/build/UnliftIO.dyn_o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
Preprocessing test suite 'unliftio-spec' for unliftio-0.2.19..
Building test suite 'unliftio-spec' for unliftio-0.2.19..
[1 of 9] Compiling Paths_unliftio ( dist/build/unliftio-spec/autogen/Paths_unliftio.hs, dist/build/unliftio-spec/unliftio-spec-tmp/Paths_unliftio.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[2 of 9] Compiling UnliftIO.AsyncSpec ( test/UnliftIO/AsyncSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/AsyncSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[3 of 9] Compiling UnliftIO.DirectorySpec ( test/UnliftIO/DirectorySpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/DirectorySpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[4 of 9] Compiling UnliftIO.ExceptionSpec ( test/UnliftIO/ExceptionSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/ExceptionSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[5 of 9] Compiling UnliftIO.IO.FileSpec ( test/UnliftIO/IO/FileSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/IO/FileSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[6 of 9] Compiling UnliftIO.IOSpec ( test/UnliftIO/IOSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/IOSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[7 of 9] Compiling UnliftIO.MemoizeSpec ( test/UnliftIO/MemoizeSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/MemoizeSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[8 of 9] Compiling UnliftIO.PooledAsyncSpec ( test/UnliftIO/PooledAsyncSpec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/UnliftIO/PooledAsyncSpec.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
[9 of 9] Compiling Main ( test/Spec.hs, dist/build/unliftio-spec/unliftio-spec-tmp/Main.o )
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
'apple-a7' is not a recognized processor for this target (ignoring processor)
Linking dist/build/unliftio-spec/unliftio-spec ...
running tests
Running 1 test suites...
Test suite unliftio-spec: RUNNING...
UnliftIO.Async
replicateConcurrently_
works
+++ OK, passed 100 tests.
uses a different thread per replicated action
+++ OK, passed 100 tests.
flatten
flattens all alternative trees
conc
handles sync exceptions
handles async exceptions
has an Unmasked masking state for given subroutines
allows to kill parent via timeout
throws right exception on empty
Conc Applicative instance
doesn't fork a new thread on a pure call
+++ OK, passed 100 tests.
evaluates all needed sub-routines
cleanup on brackets work
re-throws exception that happened first
Conc Alternative instance
is left associative
executes body of all alternative blocks
finishes all threads that didn't finish first
nesting works
UnliftIO.Directory
createFileLink
mirror
UnliftIO.Exception
catchSyncOrAsync
should catch sync exceptions
should catch async exceptions
should catch unliftio-wrapped async exceptions
handleSyncOrAsync
should catch sync exceptions
should catch async exceptions
should catch unliftio-wrapped async exceptions
trySyncOrAsync
should catch sync exceptions
should catch async exceptions
should catch unliftio-wrapped async exceptions
fromExceptionUnwrap
should be the inverse of toAsyncException
should be the inverse of toSyncException
pureTry
Right for defined values
Left for bottom
Right for wrapped bottom
pureTryDeep
Right for defined values
Left for bottom
Left for wrapped bottom
mapExceptionM
should convert an exception
should not convert unrelated exceptions
UnliftIO.IO.File
ensureFileDurable
ensures a file is durable with an fsync
withBinaryFile
read
write
read/write
append
sub-directory
relative-directory
modified-permissions
exception - Does not corrupt files
+++ OK, failed as expected. (after 1 test):
expected: "Hello World"
but got: "Goodbye yall"
exception - Does not leave files behind
+++ OK, failed as expected. (after 1 test):
expected: False
but got: True
delete - file
+++ OK, failed as expected. (after 1 test):
expected: True
but got: False
writeBinaryFile
write
default-permissions
withBinaryFileAtomic
read
write
read/write
append
sub-directory
relative-directory
modified-permissions
exception - Does not corrupt files
+++ OK, passed 1 test.
exception - Does not leave files behind
+++ OK, passed 1 test.
delete - file
+++ OK, passed 1 test.
writeBinaryFileAtomic
write
default-permissions
withBinaryFileDurable
read
write
read/write
append
sub-directory
relative-directory
modified-permissions
exception - Does not corrupt files
+++ OK, failed as expected. (after 1 test):
expected: "Hello World"
but got: "Goodbye yall"
exception - Does not leave files behind
+++ OK, failed as expected. (after 1 test):
expected: False
but got: True
delete - file
+++ OK, failed as expected. (after 1 test):
expected: True
but got: False
writeBinaryFileDurable
write FAILED [1]
default-permissions FAILED [2]
withBinaryFileDurableAtomic
read
write
read/write
append
sub-directory
relative-directory
modified-permissions
exception - Does not corrupt files
+++ OK, passed 1 test.
exception - Does not leave files behind
+++ OK, passed 1 test.
delete - file
+++ OK, passed 1 test.
writeBinaryFileDurableAtomic
write
default-permissions
UnliftIO.IO
getMonotonicTime
increases FAILED [3]
UnliftIO.Memoize
memoizeRef
sanity
+++ OK, passed 100 tests.
runs once
+++ OK, passed 100 tests.
runs once with exception
memoizeMVar
sanity
+++ OK, passed 100 tests.
runs once
+++ OK, passed 100 tests.
runs once with exception
runs once in multiple threads
+++ OK, passed 100 tests.
UnliftIO.PooledAsync
pooled mapConcurrencyN
Throws exception properly
total thread should be >= 1
should not spawn more than five threads for five concurrent tasks
should not spawn more than three threads for five concurrent tasks
should spawn only one thread
never uses more than the given number of pools and doesn't miss any return values
+++ OK, passed 100 tests.
pooled mapConcurrencyN_
Throws exception properly
total thread should be >= 1
find proper maximum value
find proper maximum value with 2 threads
find proper maximum value with 1 threads
make sure activity is happening in different threads
Not more than 5 threads will be spawned even if pooling is set to 8
replicate concurrencyN
Throws exception properly
total thread should be >= 1
Read tvar value should be 100
should not spawn more than five threads for five concurrent tasks
should not spawn more than three threads for five concurrent tasks
should spawn only one thread
should give empty list
should give empty list for -ve count
pooled replicateConcurrencyN_
Throws exception properly
total thread should be >= 1
find proper maximum value
Should be initial value
Failures:
test/UnliftIO/IO/FileSpec.hs:165:5:
1) UnliftIO.IO.File.writeBinaryFileDurable write
uncaught exception: IOException of type PermissionDenied
/private/tmp/nix-build-unliftio-0.2.19.drv-0/rio43881/writeBinaryFileDurable-write: openBinaryFile: permission denied (Permission denied)
To rerun use: --match "/UnliftIO.IO.File/writeBinaryFileDurable/write/"
test/UnliftIO/IO/FileSpec.hs:176:9:
2) UnliftIO.IO.File.writeBinaryFileDurable default-permissions
expected: Permissions {readable = True, writable = True, executable = False, searchable = False}
but got: Permissions {readable = True, writable = False, executable = False, searchable = False}
To rerun use: --match "/UnliftIO.IO.File/writeBinaryFileDurable/default-permissions/"
test/UnliftIO/IOSpec.hs:14:7:
3) UnliftIO.IO.getMonotonicTime increases
predicate failed on: 0.0
To rerun use: --match "/UnliftIO.IO/getMonotonicTime/increases/"
Randomized with seed 1698954143
Finished in 7.8185 seconds
118 examples, 3 failures
Test suite unliftio-spec: FAIL
Test suite logged to: dist/test/unliftio-0.2.19-unliftio-spec.log
0 of 1 test suites (0 of 1 test cases) passed.
builder for '/nix/store/c5yfj9bg2qysqvz255v14mkvsrh98k29-unliftio-0.2.19.drv' failed with exit code 1
``
Why not make withRunInIO
properly polymorphic? There is no impredicativity involved:
withRunInIO :: MonadUnliftIO m => ((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO inner = withUnliftIO $ \u -> inner (unliftIO u)
Then
race :: MonadUnliftIO m => m a -> m b -> m (Either a b)
race a b = withRunInIO $ \runInIO -> A.race (runInIO a) (runInIO b)
When compiling with ghc-9.2.3
:
unliftio > /.../UnliftIO/Internals/Async.hs:513:3: warning: [-Wnoncanonical-monoid-instances]
unliftio > Noncanonical ‘mappend’ definition detected
unliftio > in the instance declaration for ‘Monoid (Conc m a)’.
unliftio > ‘mappend’ will eventually be removed in favour of ‘(<>)’
unliftio > Either remove definition for ‘mappend’ (recommended) or define as ‘mappend = (<>)’
unliftio > See also: https://gitlab.haskell.org/ghc/ghc/-/wikis/proposal/semigroup-monoid
unliftio > |
unliftio > 513 | mappend = liftA2 mappend
unliftio/unliftio/src/UnliftIO/Internals/Async.hs
Lines 510 to 514 in de13c44
I've been trying to define a MonadUnliftIO
instance for haskeline's InputT
, i.e. something like
instance MonadUnliftIO m => MonadUnliftIO (InputT m) where,
or rather for a newtype wrapper around it. Of course, I wouldn't be asking if I had succeeded.
Should I expect this to be possible if I do not have access to the internals of InputT
?
In this special case, there might be work-arounds via either the low-level IO module, or via haskeline's MonadException
stuff, but of course this doesn't generalize.
#80 introduced catchSyncOrAsync
and handleSyncOrAsync
. It works well if a handler tries to catch SomeExeption
. However, if the type of an asynchronous exception is specified, it does not catch it. This is probably because they do not take care of the async wrapper.
import Control.Concurrent hiding (throwTo)
import UnliftIO.Exception
import UnliftIO.Async
data Kill = Kill deriving (Show)
instance Exception Kill
main :: IO ()
main = do
mvar <- newEmptyMVar
concurrently_ (foo mvar) (bar mvar)
foo :: MVar ThreadId -> IO ()
foo mvar = handleSyncOrAsync handler $ do
tid <- myThreadId
putMVar mvar tid
threadDelay 5000000
where
handler Kill = putStrLn "foo Killed"
-- handler (SomeException e) = putStrLn $ "foo " ++ show e
bar :: MVar ThreadId -> IO ()
bar mvar = do
tid <- takeMVar mvar
throwTo tid Kill
Handler
from safe-exceptions
has Functor
instance:
https://hackage.haskell.org/package/safe-exceptions-0.1.7.2/docs/Control-Exception-Safe.html#t:Handler
Is it possible to add Functor
to unliftio
s Handler
?
I've converted some of my code over to using MonadUnliftIO, but I still have a lot of code that uses the Streaming package.
[https://hackage.haskell.org/package/streaming-0.1.4.5/docs/Streaming-Internal.html]
Here's the ADT for it:
data Stream f m r = Step !(f (Stream f m r))
| Effect (m (Stream f m r))
| Return r
This uses MonadBase, MonadResource, MonadCatch etc, but is there any way to get this to work to support MonadUnliftIO instead?
Thanks for any help!
Grant
We should expose our withHandleFd
function somewhere because when you want to do something like fchmod()
(which needs an Fd
) on the Handle
, the most luring solution is System.Posix.IO
's handleToFd
, which is brutally wrong because
This function has the side effect of closing the Handle
If you use handleToFd
(which I just did on my server, oops), it will just mark the Handle
as closed (but keep the underlying Fd open), so then the hClose
that unliftio does will be silently ignored, and the Fd will be leaked until the server crashes (and so did mine).
So I think we should make our better withHandleFd
publicly available, and write somewhere in the module that this is what should be used if you need low-level FD access from withBinaryFile*
.
cc @lehins
I ran hlint over unliftio
and unliftio-core
and found:
- [ ] Avoid lambda, 2 hints
- [ ] Avoid lambda using `infix`, 3 hints
- [ ] Eta reduce, 1 hint
- [ ] Move brackets to avoid $, 14 hints
- [ ] Redundant bracket, 34 hints
- [ ] Replace case with maybe, 1 hint
- [ ] Unused LANGUAGE pragma, 12 hints
- [ ] Use <$>, 2 hints
- [ ] Use asum, 4 hints
- [ ] Use camelCase, 19 hints
- [ ] Use const, 4 hints
- [ ] Use even, 3 hints
- [ ] Use fewer imports, 1 hint
- [ ] Use fmap, 13 hints
- [ ] Use lambda-case, 1 hint
- [ ] Use newTVarIO, 3 hints
- [ ] Use readTVarIO, 8 hints
- [ ] Use void, 1 hint
- [ ] Use when, 2 hints
Which of these do we care about?
Hi, I use rio (and thus unliftio) a lot, and would like to get unlifted versions of Control.Concurrent.QSem and Control.Concurrent.QSemN from RIO. I know that sometimes rio does not re-export a module or a function because it has problems (like Control.Exception), and I would like to know such reasons. Is there any problem with QSem modules?
I often find scenarios where I need to easily limit concurrent jobs. For example, I spawn a child process for each request, and wait for it to finish before sending back the response. I would like to limit the number of processes running in order to avoid OOMs. I think QSem is best suited for this kind of logics. I know I can use Chan, but it requires spawning threads as workers and it's difficult to send back the response. I can also use Pool, but it seems unnecessary because the child processes are not reusable resources -- they always get destroyed after finish.
Would it make sense to add an Eq
instance for StringException
? I'm writing tests for functions that should handle arbitrary errors, and it would be nice to just do
let e = stringException "asdf"
res <- tryAny $ withFoo (\_ -> throwIO e)
res `shouldBe` Left e
Right now, I'm forced to write my own exception type and use that.
I've noticed that unliftio
's UnliftIO.Temporary
doesn't lift temporary
's System.IO.Temp
, but instead reimplements most of that module.
As far as I understand, the main difference between both is that temporary
will create the file/temporary template based on a random string, while unliftio
will use the process's PID. This may actually have surprising behavior with concurrent programs (e.g., see this issue: UnkindPartition/temporary#8), where race conditions can happen. temporary
mitigates this problem.
Is there any reason unliftio
reimplements the module? Wouldn't it make it easier to keep up with updates in that library?
One more thing: why not re-export getCanonicalTemporaryDirectory
?
Maybe I am missing something, but it seems like it is not exported...
So, I guess I have to use this now because commercialhaskell/stackage#3256. That's fine, but I'm not finding any guidance on migrating away from lifted-base
aside from removing it from my library. Is there an equivalent?
When defining monad transformers as newtypes over IdentityT
or ReaderT r
, I'd like to simply derive an instance for UnliftIO
with the newtype
strategy,
newtype Newtype m a = Newtype (m a)
deriving newtype (Functor, Applicative, Monad, MonadIO, MonadUnliftIO)
However, this currently fails with the error
• Couldn't match representation of type ‘m (UnliftIO (Newtype m))’
with that of ‘m (UnliftIO m)’
arising from the coercion of the method ‘askUnliftIO’
from type ‘m (UnliftIO m)’
to type ‘Newtype m (UnliftIO (Newtype m))’
NB: We cannot know what roles the parameters to ‘m’ have;
we must assume that the role is nominal
• When deriving the instance for (MonadUnliftIO (Newtype m))
This could be avoided by moving the askUnliftIO
method out of the class definition. This is pretty much the breaking part of #13.
[ 7 of 13] Compiling UnliftIO.Instances ( src/UnliftIO/Instances.hs, dist/build/UnliftIO/Instances.dyn_o )
src/UnliftIO/Instances.hs:11:10: error:
Duplicate instance declarations:
instance MonadUnliftIO m => MonadUnliftIO (LoggingT m)
-- Defined at src/UnliftIO/Instances.hs:11:10
instance MonadUnliftIO m => MonadUnliftIO (LoggingT m)
-- Defined in ‘Control.Monad.Logger’
|
11 | instance MonadUnliftIO m => MonadUnliftIO (LoggingT m) where
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/UnliftIO/Instances.hs:17:10: error:
Duplicate instance declarations:
instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m)
-- Defined at src/UnliftIO/Instances.hs:17:10
instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m)
-- Defined in ‘Control.Monad.Logger’
|
17 | instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m) where
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Related: #74
This is a minimal reproduction of the issue we're seeing.
describe "withException" $ do
it "should work when withAsync is in the handler" $ do
let
action =
error "oops"
`onException` do
let
timerAction n = do
threadDelay 1000000
when (n < 10) $ do
timerAction (n + 1)
withAsync (timerAction 0) $ \a -> do
cancel a
action
`shouldThrow`
errorCall "oops"
This should finish instantaneously, but it actually waits for timerAction
to complete - all 10 seconds of it. cancel
is therefore broken inside of a withException
or onException
or even a bracket
call.
What's very surprising about this behavior is that catch
doesn't share it. catch
works exactly like you'd expect, even though a very simple implementation of withException
is withException action handler = catch action (\e -> handler e >> throwIO e)
.
I wrote an implementation of what I've called "companion threads" for Stack:
It's theoretically a general-purpose concept, and would fit in well with this library: it introduces no additional dependencies, and nicely generalizes to MonadUnliftIO
. However, I'm not sure if the idea is fully fleshed out yet and warrants being included here. Feedback welcome.
module UnliftExcept where
import Control.Monad.Except
import UnliftIO
instance (MonadUnliftIO m, Exception e) => MonadUnliftIO (ExceptT e m) where
withRunInIO exceptToIO = ExceptT $ try $ do
withRunInIO $ \runInIO ->
exceptToIO (runInIO . (either throwIO pure <=< runExceptT))
This is probably Bad for reasons I haven't figured out yet, but it works.
Is throwSTM
not exported from UnliftIO.STM
on purpose, or was just forgotten about? If it is the former, I could supply a PR with adding it.
EDIT: the text/title of this issue are confused - I missed that the test that could see-through the wrapper was actually catching SomeException
and doing fromExceptionUnwrap
on it.
This test illustrates the issue:
it "should catch unliftio-wrapped sync exceptions" $ do
result <- (`catchSyncOrAsync` return) $ throwIO Control.Exception.ThreadKilled
result `shouldBe` Control.Exception.ThreadKilled
This test currently fails:
Failures:
test/UnliftIO/ExceptionSpec.hs:60:7:
1) UnliftIO.Exception.catchSyncOrAsync should catch unliftio-wrapped async exceptions
expected: Just Exception1
but got: Nothing
To rerun use: --match "/UnliftIO.Exception/catchSyncOrAsync/should catch unliftio-wrapped async exceptions/"
We're doing throwIO ThreadKilled
, which throws SomeException (SyncExceptionWrapper ThreadKilled)
.
Meanwhile, catchSyncOrAsync
is not looking "through" the SyncExceptionWrapper
:
catchSyncOrAsync :: (MonadUnliftIO m, Exception e) => m a -> (e -> m a) -> m a
catchSyncOrAsync f g = withRunInIO $ \run -> run f `EUnsafe.catch` \e -> run (g e)
Most of the file operations in UnliftIO.IO.File
have disclaimers like this:
This function behaves the same as
withBinaryFile
on Windows platforms.
I presume that this means that atomicity and durability are not implemented on Windows.
If so, could the same guarantees be implemented on Windows too?
System: Ubuntu 22.04, on a PRoot environment on AAch64.
Unliftio v. 0.2.23.0
When I do:
module Main (main) where
import UnliftIO.IO.File
import Data.ByteString
main :: IO ()
main = do
writeBinaryFile "writeBinaryFile.txt" bs
writeBinaryFileAtomic "writeBinaryFileAtomic.txt" bs
writeBinaryFileDurable "writeBinaryFileDurable.txt" bs
writeBinaryFileDurableAtomic "writeBinaryFileDurableAtomic.txt" bs
where
bs = pack [65 .. 75]
I get 4 files, however, the ones using the atomic variant are empty:
emilio@localhost:~/testrio$ ls -l
total 1312
-rwxr-xr-x. 1 emilio emilio 1334440 Dec 28 15:18 testrio-exe
-rw-rw-r--. 1 emilio emilio 11 Dec 28 15:20 writeBinaryFile.txt
-rw-rw-rw-. 1 emilio emilio 0 Dec 28 15:20 writeBinaryFileAtomic.txt
-rw-rw-r--. 1 emilio emilio 11 Dec 28 15:20 writeBinaryFileDurable.txt
-rw-rw-rw-. 1 emilio emilio 0 Dec 28 15:20 writeBinaryFileDurableAtomic.txt
The same problem does not happen (i.e. it works as expected) when running the code on a regular virtualized environment on the same OS and hw architecture.
Any hints as to what might be happening?
amazonka-1.6.1
(the latest release) depends on unliftio-core (==0.1.*)
, the latest version of which will not build with GHC 8.10 due to the dependency on base (>=4.5 && <4.14)
. I've got unliftio-core to build just fine with GHC 8.10 by manually allowing base >=4.5 && <4.15
. I propose making a revision on the package in Hackage to allow this so that people can use amazonka with GHC 8.10.
What do you think?
The base<4.14 prevents unliftio from being built with GHC 8.10.1. Everything seems to work after relaxing the bound, though.
After my recent pull request gets merged, there will be no uses of withUnliftIO
in the codebase. Instead it will be
withRunInIO :: MonadUnliftIO m => ((forall a. m a -> IO a) -> IO b) -> m b
everywhere. I think, the library should be build around this function instead of askUnliftIO
. Consider a type class with a very similar shape:
class MonadCatch m => MonadMask m where
mask :: ((forall a. m a -> m a) -> m b) -> m b
-- `uninterruptibleMask` also
It's not something like
class MonadCatch m => MonadMask m where
askMask :: m (Mask m)
This would be less readable and more clunky.
So I think it should be
class MonadIO m => MonadUnliftIO m where
withRunInIO :: ((forall a. m a -> IO a) -> IO b) -> m b
Regarding laws for withRunInIO
, how about this one:
forall m a. MonadUnliftIO m => pi (x :: m a) -> withRunInIO ($ x) ~ x
?
Having both withRunInIO
and askUnliftIO
in the type class along with a MINIMAL
pragma is an option, but to me it looks like it complicates the library. It is more convenient to define withRunInIO
than askUnliftIO
, because there are no newtypes involved:
instance MonadUnliftIO m => MonadUnliftIO (ReaderT r m) where
withRunInIO k =
ReaderT $ \r -> withRunInIO $ \run -> k $ run . flip runReaderT r
I also like that return
is not used in the definition of withRunInIO
. This makes it possible to generalize MonadUnliftIO
to other things, maybe some functors. Just in a case.
All in all, I think, withRunInIO
is the way to go.
UnliftIO.Concurrent
provides a function called forkWithUnmask
, which is an unlifted variant of forkIOWithUnmask
. Now, all other unlifted functions provided by the library match the name of their original -- but this does one does not. Was that choice intentional?
The UnliftIO.Exception
module contains a large copy/paste of code and types from safe-exceptions
, including items like AsyncExceptionWrapper
, SyncExceptionWrapper
, etc.
Program behavior may change if you switch from Control.Exception.Safe.throwTo
to UnliftIO.Exception.throwTo
- if you do a catch
and expect an Control.Exception.Safe.AsyncExceptionWrapper
, then you'll fail to catch the wrapped type.
Since the types are the same, it seems to make sense to unify them.
This could mean depending on safe-exceptions
directly, or factoring the type out into a separate package.
If we do depend on safe-exceptions
directly, then we can also unify Handler
#101, since exceptions
is a dependency of safe-exceptions
.
Forgot to mention, a consequence of #55 is that this default implementation will make withRunInIO
loop through askUnliftIO
for people who define an empty instance (or who derive anyclass
).
unliftio/unliftio-core/src/Control/Monad/IO/Unlift.hs
Lines 60 to 62 in d9946e6
Isn't the law equivalent to "lifting must be invertible"?
UnliftIO.IO.File
currently offers only binary mode file operations.
It would be nice if text mode operations were offered too, to simplify writing text files in a cross-platform way: On Windows, text mode writes change LF
line endings to CRLF
. See openBinaryFile
:
On Windows, reading a file in text mode (which is the default) will translate CRLF to LF, and writing will translate LF to CRLF. This is usually what you want with text files. With binary files this is undesirable; also, as usual under Microsoft operating systems, text mode treats control-Z as EOF. Binary mode turns off all special treatment of end-of-line and end-of-file characters. (See also hSetBinaryMode.)
What do you think about adding
unlift :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b
unlift m x = do
runInIO <- askRunInIO
liftIO $ m $ runInIO x
to Control.Monad.IO.Unlift
? This is handy when you have a IO a -> IO b
, and avoids a little bit of boilerplate.
Usage example:
runSTControl lock stControl prepare =
maybe (throwIO Locked) return =<< unlift (withLockTry lock) do
where withLockTry
is withLockTry :: Lock -> IO a -> IO (Maybe a)
from extra
.
It would be great if UnliftIO.Exception
could define
-- Same as catch, except only catches async, rethrowing sync
catchAsync = ...
-- Explicitly catches sync and async exceptions
catchSyncOrAsync = Unsafe.catch
along with similar functions for handle
and try
. I have some code that should handle async exceptions as well, but I'd like to avoid lifting my overall ban on Control.Exception
, even for a single module.
Thoughts?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.