Reputation: 23
The error message show below.
If remove the line in code hClose temph
, the program can be compiled successfully.
tempfile.hs:85:8: error:
• Couldn't match type ‘a’ with ‘()’
‘a’ is a rigid type variable bound by
the type signature for:
withTempFile :: forall a.
String -> (FilePath -> Handle -> IO a) -> IO a
at tempfile.hs:62:1-62
Expected type: IO a
Actual type: IO ()
• In a stmt of a 'do' block: hClose temph
In the expression:
do tempdir <- getTemporaryDirectory
(tempfile, temph) <- openTempFile tempdir pattern
func tempfile temph
hClose temph
In an equation for ‘withTempFile’:
withTempFile pattern func
= do tempdir <- getTemporaryDirectory
(tempfile, temph) <- openTempFile tempdir pattern
func tempfile temph
....
• Relevant bindings include
func :: FilePath -> Handle -> IO a (bound at tempfile.hs:63:22)
withTempFile :: String -> (FilePath -> Handle -> IO a) -> IO a
(bound at tempfile.hs:63:1)
|
85 | hClose temph
| ^^^^^^^^^^^^
The code
withTempFile :: String -> (FilePath -> Handle -> IO a) -> IO a
withTempFile pattern func =
do -- The library ref says that getTemporaryDirectory may raise on
-- exception on systems that have no notion of a temporary directory.
-- So, we run getTemporaryDirectory under catch. catch takes
-- two functions: one to run, and a different one to run if the
-- first raised an exception. If getTemporaryDirectory raised an
-- exception, just use "." (the current working directory).
--tempdir <- catch (getTemporaryDirectory) (\_ -> return ".")
tempdir <- getTemporaryDirectory
(tempfile, temph) <- openTempFile tempdir pattern
-- Call (func tempfile temph) to perform the action on the temporary
-- file. finally takes two actions. The first is the action to run.
-- The second is an action to run after the first, regardless of
-- whether the first action raised an exception. This way, we ensure
-- the temporary file is always deleted. The return value from finally
-- is the first action's return value.
--finally (func tempfile temph)
-- (do hClose temph
-- removeFile tempfile)
func tempfile temph
-- putStrLn temph
hClose temph
--removeFile tempfile
Upvotes: 0
Views: 53
Reputation: 48572
Since the hClose
is last, that's what comes out of the do
block. You need the result of func
to come out of the do
block, so do this instead:
rv <- func tempfile temph
hClose temph
return rv
You still need to do more work to make it exception-safe, but that's enough to make it compile and work right on the happy path.
Upvotes: 4