-
Notifications
You must be signed in to change notification settings - Fork 721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IO functions for reading. Remove PoolMetadataFile type #5194
Conversation
4c3373f
to
65aa5e9
Compare
@@ -76,7 +76,7 @@ newtype File content (direction :: FileDirection) = File | |||
handleFileForWritingWithOwnerPermission | |||
:: FilePath | |||
-> (Handle -> IO ()) | |||
-> IO (Either (FileError ()) ()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can't be ()
because we wan't to use the functions for reading things with e
other than ()
.
The fact that e
is here at all is problematic. e
is for decode errors, but why should functions purely used for reading and writing files and do no decode at all have to concern themselves with decode errors? Having the e
here produce type-inference problems down the line.
See #5194 (comment)
@@ -66,7 +67,7 @@ createFileWithOwnerPermissions :: HasTextEnvelope a => File () Out -> a -> Prope | |||
createFileWithOwnerPermissions targetfp value = do | |||
result <- liftIO $ writeLazyByteStringFileWithOwnerPermissions targetfp $ textEnvelopeToJSON Nothing value | |||
case result of | |||
Left err -> failWith Nothing $ displayError err | |||
Left err -> failWith Nothing $ displayError @(FileError ()) err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compiler needs to infer a concrete type for e
because it "needs" to display the error. The compile doesn't actually need the display the error because the constructor that has e
is never used, but the compiler doesn't know that. We have to help the compiler by fixing e = ()
because there is an Error ()
instance this work.
It's unpleasant we have to help the compiler infer a type to display an error that never gets displayed, but our errors are tightly coupled.
65aa5e9
to
f2e11b9
Compare
@@ -117,18 +123,39 @@ handleFileForWritingWithOwnerPermission path f = do | |||
(targetDir, targetFile) = splitFileName path | |||
#endif | |||
|
|||
readByteStringFile :: () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tbh, a typeclass would work here better instead of having all those specialized functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an objection to type classes.
You're welcome to put up a PR and we can see what it looks like.
data FileError e = FileError FilePath e
| FileErrorTempFile
FilePath
-- ^ Target path
FilePath
-- ^ Temporary path
Handle
| FileIOError FilePath IOException
deriving (Show, Eq, Functor) Firstly, do we really need to have a type parameter in My suggestion here would be to go similarly to https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Exception.html : remove type parameter, and make type existential and provide access to the field value via existing Error class. And in the rare need for handling particular error type returned, we could just simply cast and handle it. What do you think? |
These are the types of
We need to be able to throw these error types along side File ones because functions exist that produce both kinds of errors. This is another example of where The purely file functions can throw readByteStringFile :: ()
=> e `CouldBe` FileError
=> File content In
-> ExceptT (Variant e) IO ByteString
decodeMyType :: ()
=> e `CouldBe` DecodeError
=> ByteString
-> ExceptT (Variant e) IO MyType
readFileAndDecodeMyType :: ()
=> e `CouldBe` FileError
=> e `CouldBe` DecodeError
=> File MyType In
=> ByteString
-> ExceptT (Variant e) IO MyType
readFileAndDecodeMyType file = readByteStringFile file >>= decodeMyType Full separation of concerns. We don't have to:
|
65269e6
to
f1f728c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
f1f728c
to
2266694
Compare
bd92209
to
6fab19a
Compare
6fab19a
to
ad1e3b6
Compare
Description
Add IO functions for reading files.
Remove
PoolMetadataFile
type and useFile
type instead.Work around some type-inference issues that shouldn't exist.
Checklist
See Runnings tests for more details
CHANGELOG.md
for affected package.cabal
files are updatedhlint
. See.github/workflows/check-hlint.yml
to get thehlint
versionstylish-haskell
. See.github/workflows/stylish-haskell.yml
to get thestylish-haskell
versionghc-8.10.7
andghc-9.2.7
Note on CI
If your PR is from a fork, the necessary CI jobs won't trigger automatically for security reasons.
You will need to get someone with write privileges. Please contact IOG node developers to do this
for you.