Reputation: 22106
What I tried:
main :: IO ()
main = do
let eitherSuccessOrErrorLine = inshellWithErr "stack build" empty
stackBuildOutput <- strict $ case eitherSuccessOrErrorLine of
Shell (Left line) -> line
Shell (Right line) -> line
putStr stackBuildOutput
Error message:
src/Main.hs:34:12: error:
• Couldn't match expected type ‘Turtle.Shell.FoldShell
(Either Turtle.Line.Line Turtle.Line.Line) r0
-> IO r0’
with actual type ‘Either (Shell Turtle.Line.Line) b0’
• In the pattern: Left line
In the pattern: Shell (Left line)
In a case alternative: Shell (Left line) -> line
|
34 | Shell (Left line) -> line
| ^^^^^^^^^
src/Main.hs:35:12: error:
• Couldn't match expected type ‘Turtle.Shell.FoldShell
(Either Turtle.Line.Line Turtle.Line.Line) r1
-> IO r1’
with actual type ‘Either a0 (Shell Turtle.Line.Line)’
• In the pattern: Right line
In the pattern: Shell (Right line)
In a case alternative: Shell (Right line) -> line
|
35 | Shell (Right line) -> line
| ^^^^^^^^^^
Upvotes: 0
Views: 124
Reputation: 995
The problem is that you're attempting to pattern match on the result of runShellWithErr
. runShellWithErr
does return a Shell (Left Line) (Right Line)
, but Shell
is defined thusly:
newtype Shell a = Shell { _foldShell:: forall r . FoldShell a r -> IO r }
Which is why your pattern is failing.
Instead of trying to pattern match on the result of runShellWithErr
, it's cleaner to extract the line from the Either
within the Shell
monad. Like this:
main :: IO ()
main = do
let successOrErrorLine = do
buildOutput <- inshellWithErr "stack build" empty
return $ case buildOutput of
Left line -> line
Right line -> line
result <- strict successOrErrorLine
putStr $ show result
Which can be done more succinctly as
main :: IO ()
main = do
let successOrErrorLine = (either id id) <$> (inshellWithErr "stack build" empty)
result <- strict successOrErrorLine
putStr $ show result
Upvotes: 1
Reputation: 22106
Solution was to create a function:
runStackBuild :: Shell ()
runStackBuild = do
out <- inshellWithErr "stack build" empty
liftIO $ putStrLn $ lineToText $ bifold out
and call it from main :: IO ()
:
putStrLn "Starting `stack build`"
sh runStackBuild
putStrLn "Finished `stack build`"
Upvotes: 1