问题
If I have a returned type of an expression/value:
:: Control.Monad.IO.Class.MonadIO m =>
m (Either PDFInfoError PDFInfo)
How do I get the PDFInfo out of it? Perhaps more importantly, what process does one use to figure such things out. I'd like to leverage typed holes or some other process to be able to reason through these types (no pun intended) of questions on my own. Still reading through my first Haskell book, but wanting to understand how a more experienced Haskeller would solve this using tools.
Perhaps it will help to have the greater context of the problem (attempting to use a typed hole to let ghc help me find what I am missing to get the PDFInfo result so that I can call pdfInfoTitle on it):
module Main where
import Text.PDF.Info
main :: IO ()
main = do
pdfInfoTitle $ _ pdfInfo "foo.pdf"
回答1:
Here's a compiling example:
module Main where
import Text.PDF.Info
main :: IO ()
main = do
result <- pdfInfo "foo.pdf"
case result of
Left someError -> do
putStrLn "Oh, no!"
print someError
Right info -> do
putStrLn "OK! Got info!"
print (pdfInfoTitle info)
The idea is: in your type, the monad m
can be chosen as we wish as long as m
belong to class MonadIO
. m = IO
satisfies that, so we can "run" pdfInfo "foo.pdf"
inside main
, much like putStrLn "hello"
or l <- geTLine
or any other IO action.
(Whenever you have MonadIO m => ...
, you can always pretend that m = IO
. They type is slightly more general than that, but keeping things simple helps intuition.)
So, we can use result <- pdfInfo "foo.pdf"
.
Here, result
has type whatever is inside m
, that is Either PDFInfoError PDFInfo
. Hence, result
is either an error (wrapped under Left
) or the actual info (wrapped using Right
).
We can then use case result of
to branch on the two possibilities, and handle them accordingly.
来源:https://stackoverflow.com/questions/58032008/how-to-plug-this-type-hole