Gabriella439 / turtle

Shell programming, Haskell style

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How can I thread a directory created with mktempdir through multiple functions

ParetoOptimalDev opened this issue · comments

Given:

main :: IO ()
main = (Turtle.sh $ do
  tmpDir       <- Turtle.mktempdir "/tmp" "turtle"
  useTmpDir1 tmpDir
  useTmpDir2 tmpDir
  Turtle.die "we're done")

useTmpDir1 tmpDir = do
  putStrLn "useTmpDir1"
  Turtle.cd tmpDir

useTmpDir2 tmpDir = do
  putStr "useTmpDir2"
  Turtle.cd tmpDir

I get:

λ> main
useTmpDir1
useTmpDir2*** Exception: getCurrentDirectory:getWorkingDirectory: does not exist (Current working directory no longer exists)

I've re-read https://hackage.haskell.org/package/managed-1.0.9/docs/Control-Monad-Managed.html a few times and tried envisioning what the above code would look like in terms of something like:

main =
    withFile "inFile.txt" ReadMode $ \inHandle ->
        withFile "outFile.txt" WriteMode $ \outHandle ->
            copy inHandle outHandle

But it's just not clicking for whatever reason.

Can anyone tell me how I should ensure the two helper functions stay within the scope of that Managed resource and if it's not too much to ask, what it'd look like in nested form?

Continuing to try and figure this out for myself...

I can't quite understand it that way because the scope of Managed doesnt stay alive through multiple functions but using the with pattern it would.

For instance:

main :: IO ()
main =
    withFile "inFile.txt" ReadMode $ \inHandle ->
            useHandle1 inHandle
            useHandle2 inHandle

useHandle1 handle = do
  putStrLn "pretend this is writing to handle"

useHandle2 handle = do
  putStrLn "pretend this is writing to handle"

I think then I'll want to somehow follow this documentation:

If you need to acquire a resource for a long-lived loop, you can instead acquire the resource first and run the loop in IO, using either of the following two equivalent idioms:

with resource (\r -> forever (useThe r))

do r <- resource
   liftIO (forever (useThe r))

I tried code following that last piece of documentation and it didn't seem to help here:

-- doesn't work
try1 = (Turtle.sh $ do
  tmpDir <- Turtle.mktempdir "/tmp" "turtle"
  liftIO $ useTmpDir1 tmpDir
  liftIO $ useTmpDir2 tmpDir)

-- doesn't work
try2 = 
  let tmpDir = Turtle.mktempdir "/tmp" "turtle"
  in Turtle.with tmpDir $ \d -> do
    useTmpDir1 d
    useTmpDir2 d

Another thing to try I could think of:

try3 = Turtle.runManaged $ do
  tmpDir <- Turtle.mktempdir "/tmp" "turtle"
  useTmpDir1 tmpDir
  useTmpDir2 tmpDir

Given that the liftio example from try1 exists in the dhall codebase I'm assuming that this not working has more to do with me using ghci an dthings will work fine if I just run the binary.

It does, closing this.