如何使用 Haskell Turtle 库打印路径?
How to print paths using Haskell Turtle library?
要学习一点 Turtle
,我认为修改教程中的示例会很好。我选择从输出的每一行中删除冗余 "FilePath",认为这将是一个简单的练习。
然而,尽管作者努力使他的库易于使用,但我几乎没能用它来解决这个简单的问题。
我尝试了所有我看到的东西,看起来可以让我以某种方式将 >>=
从 IO
提升到 Shell
:MonadIO
、FoldM
、 liftIO
、_foldIO
没有成功。我变得很沮丧,只有通过阅读 Turtle
源代码,我才能找到似乎可行的东西(想到 "no obvious defects")。
为什么这么难?如何使用此库的 API 从逻辑上得出解决方案?
#!/usr/bin/env stack
-- stack --resolver lts-8.17 --install-ghc runghc --package turtle --package lens
{-# LANGUAGE OverloadedStrings #-}
import Turtle
import Control.Lens
import Control.Foldl as Foldl
import Filesystem.Path.CurrentOS
import Data.Text.IO as T
import Data.Text as T
main = do
homedir <- home
let paths = lstree $ homedir </> "projects"
let t = fmap (Control.Lens.view _Right . toText) paths
customView t
customView s = sh (do
x <- s
liftIO $ T.putStrLn x)
您不会将 >>=
从 IO
提升到 Shell
。 Shell
已经有一个 Monad
实例,它自带 >>=
函数。相反,您要么将 IO
操作提升为 Shell
与 liftIO
或 运行 或 shell 与 fold
或 foldM
。当您不关心结果时,使用 sh
到 运行 Shell
。
我相信你的例子可以简化为
main = sh $ do
homedir <- home
filepath <- lstree $ homedir </> "projects"
case (toText filepath) of
Right path -> liftIO $ T.putStrLn x
Left approx -> return () -- This shouldn't happen
至于从 FilePath
获取字符串的困难,我认为这不能归咎于 Turtle 作者。我觉得可以简化为
stringPath :: FilePath -> String
stringPath filepath =
case (toText filePath) of -- try to use the human readable version
Right path -> T.unpack path
Left _ -> encodeString filePath -- fall back on the machine readable one
结合这将把例子简化为
main = sh $ do
homedir <- home
filepath <- lstree $ homedir </> "projects"
liftIO $ putStrLn (stringPath filepath)
或
main = view $ do
homedir <- home
filepath <- lstree $ homedir </> "projects"
return $ stringPath filepath
要学习一点 Turtle
,我认为修改教程中的示例会很好。我选择从输出的每一行中删除冗余 "FilePath",认为这将是一个简单的练习。
然而,尽管作者努力使他的库易于使用,但我几乎没能用它来解决这个简单的问题。
我尝试了所有我看到的东西,看起来可以让我以某种方式将 >>=
从 IO
提升到 Shell
:MonadIO
、FoldM
、 liftIO
、_foldIO
没有成功。我变得很沮丧,只有通过阅读 Turtle
源代码,我才能找到似乎可行的东西(想到 "no obvious defects")。
为什么这么难?如何使用此库的 API 从逻辑上得出解决方案?
#!/usr/bin/env stack
-- stack --resolver lts-8.17 --install-ghc runghc --package turtle --package lens
{-# LANGUAGE OverloadedStrings #-}
import Turtle
import Control.Lens
import Control.Foldl as Foldl
import Filesystem.Path.CurrentOS
import Data.Text.IO as T
import Data.Text as T
main = do
homedir <- home
let paths = lstree $ homedir </> "projects"
let t = fmap (Control.Lens.view _Right . toText) paths
customView t
customView s = sh (do
x <- s
liftIO $ T.putStrLn x)
您不会将 >>=
从 IO
提升到 Shell
。 Shell
已经有一个 Monad
实例,它自带 >>=
函数。相反,您要么将 IO
操作提升为 Shell
与 liftIO
或 运行 或 shell 与 fold
或 foldM
。当您不关心结果时,使用 sh
到 运行 Shell
。
我相信你的例子可以简化为
main = sh $ do
homedir <- home
filepath <- lstree $ homedir </> "projects"
case (toText filepath) of
Right path -> liftIO $ T.putStrLn x
Left approx -> return () -- This shouldn't happen
至于从 FilePath
获取字符串的困难,我认为这不能归咎于 Turtle 作者。我觉得可以简化为
stringPath :: FilePath -> String
stringPath filepath =
case (toText filePath) of -- try to use the human readable version
Right path -> T.unpack path
Left _ -> encodeString filePath -- fall back on the machine readable one
结合这将把例子简化为
main = sh $ do
homedir <- home
filepath <- lstree $ homedir </> "projects"
liftIO $ putStrLn (stringPath filepath)
或
main = view $ do
homedir <- home
filepath <- lstree $ homedir </> "projects"
return $ stringPath filepath