Haskell 哈斯凯尔海龟-劈壳
是否可以在Turtle library(Haskell)中拆分一个Shell,并对其中任何一个进行不同的操作,从而使原始Shell只运行一次Haskell 哈斯凯尔海龟-劈壳,haskell,haskell-turtle,Haskell,Haskell Turtle,是否可以在Turtle library(Haskell)中拆分一个Shell,并对其中任何一个进行不同的操作,从而使原始Shell只运行一次 /---- shell2 ---Shell1 --/ \ \-----shell3 比如说怎么办? do let lstmp = lstree "/tmp" view lstmp view $ do path <- lstmp x <- l
/---- shell2
---Shell1 --/
\
\-----shell3
比如说怎么办?
do
let lstmp = lstree "/tmp"
view lstmp
view $ do
path <- lstmp
x <- liftIO $ testdir path
return x
do
设lstmp=lstree“/tmp”
视图lstmp
查看$do
路径听起来像是在寻找类似async
的东西,从第一个shell中分离shell,然后等待它们返回async
是一个功能非常强大的库,可以实现比下面的示例多得多的功能,但它为您的需求提供了一个非常简单的解决方案:
import Control.Concurrent.Async
import Turtle.Shell
import Turtle.Prelude
main :: IO ()
main = do
let lstmp1 = lstree "/tmp"
let lstmp2 = lstree "/etc"
view lstmp1
view lstmp2
job1 <- async $ view $ do
path <- lstmp1
x <- liftIO $ testdir path
return x
job2 <- async $ view $ do
path <- lstmp2
x <- liftIO $ testdir path
return x
wait job1
wait job2
import Control.Concurrent.Async
进口龟壳
进口海龟。序曲
main::IO()
main=do
设lstmp1=lstree“/tmp”
设lstmp2=lstree“/etc”
视图lstmp1
视图lstmp2
job1您将无法将一个Shell
拆分为两个同时运行的独立Shell,除非我不知道有什么神奇之处。但文件编写是对shell或其他连续内容的折叠。它内置于turtle
中,您可以使用Control.Foldl
material随时组合许多折叠并使它们同时运行-此处
foldIO :: Shell a -> FoldM IO a r -> IO r -- specializing
一个shell在引擎盖下暗地里是一个FoldM IO A r->IO r
,所以这基本上就是runShell
。为此,我们需要获得正确的Shell
和正确的组合FoldM IO
。来自foldl
包的foldmab
和foldmab
类型的整个思想是同时折叠
我认为获得正确shell的最简单方法就是让lstree
fold返回FilePath
以及testdir
的结果。你基本上是这样写的:
withDirInfo :: FilePath -> Shell (Bool, FilePath)
withDirInfo tmp = do
let lstmp = lstree tmp
path <- lstmp
bool <- liftIO $ testdir path
return (bool, path)
然后我们可以使用这个Handle->FoldM IO FilePath()
来定义两个FoldM IO(Bool,FilePath)(
)。每一个都会将不同的内容写入不同的句柄,我们可以使用
IO.withFile“tmpdirs.txt”IO.WriteMode$\h'->do
foldIO(带dirinfo“/tmp”)(sinkFilesDirs h')
withDirInfo::Turtle.FilePath->Shell(Bool,Turtle.FilePath)
withDirInfo tmp=do
设lstmp=lstreetmp
路径句柄->文件夹IO(Bool,Turtle.FilePath)()
sinkFilesDirs h'=所有文件bool)_2) (h')
--处理成对的第二个元素,其中第一个元素
--使用SinkFilePath时为true
我在做流处理,所以实际上我希望所有事情都是同步的,一行一行地进行,所以我不认为异步是答案。好的,这很好地解释了如何做。我缺少的一点是理解到,使用“L.sink”写入文件也可以是一种折叠。只是意味着我必须更多地探索Foldl的力量!
sinkFilePaths :: Handle -> FoldM IO FilePath ()
sinkFilePaths handle = L.sink (T.hPutStrLn handle . format fp)
{-#LANGUAGE OverloadedStrings #-}
import Turtle
import qualified Control.Foldl as L
import qualified System.IO as IO
import Control.Lens (_2,filtered)
import qualified Data.Text.IO as T
main = IO.withFile "tmpfiles.txt" IO.WriteMode $ \h ->
IO.withFile "tmpdirs.txt" IO.WriteMode $ \h' -> do
foldIO (withDirInfo "/tmp") (sinkFilesDirs h h')
withDirInfo :: Turtle.FilePath -> Shell (Bool, Turtle.FilePath)
withDirInfo tmp = do
let lstmp = lstree tmp
path <- lstmp
bool <- liftIO $ testdir path
return (bool, path)
sinkFilePaths :: Handle -> FoldM IO Turtle.FilePath ()
sinkFilePaths handle = L.sink (T.hPutStrLn handle . format fp)
sinkFilesDirs :: Handle -> Handle -> FoldM IO (Bool, Turtle.FilePath) ()
sinkFilesDirs h h' = allfiles <* alldirs where
allfiles :: L.FoldM IO (Bool, Turtle.FilePath) ()
allfiles = L.handlesM _2 (sinkFilePaths h)
-- handle the second element of pairs with sinkFilePaths
alldirs :: FoldM IO (Bool, Turtle.FilePath) ()
alldirs = L.handlesM (filtered (\(bool,file) -> bool) . _2) (sinkFilePaths h')
-- handle the second element of pairs where the first element
-- is true using sinkFilePaths