我正在玩 Turtle我面临着以下问题。
我想做类似的事情(在 shell 中)
ls | grep 'foo'
我尝试使用 Turtle 是
grep (prefix "foo") (ls ".") & view
但是我收到了下面的信息
Couldn't match type ‘Turtle.FilePath’ with ‘Text’
Expected type: Shell Text
Actual type: Shell Turtle.FilePath
In the second argument of ‘grep’, namely ‘(ls ".")’
In the first argument of ‘(&)’, namely
‘grep (prefix "foo") (ls ".")’
我了解 ls
返回 FilePath
而 grep
处理 Text
,那么我能做什么?
更新
显然有一些解决方案涉及从 FilePath
到 Text
来回转换。这超出了我所期望的类 shell 程序的简单性。
有人提到了find
函数,它可以以某种方式解决问题。
但是 find
相当于 find
shell 函数,我只是想做 ls | grep "foo"
。我不是要解决现实生活中的问题(如果是,我会转而使用 bash),而是尝试像在 bash 中那样组合简单的积木。不幸的是,Turtle 中的积木似乎并不那么容易组合:-(。
最佳答案
而不是 grep
, 我们可以使用 match
, 结合 MonadPlus
用于过滤的 Shell
实例:
filterByPattern :: MonadPlus m => Pattern x -> FilePath -> m FilePath
filterByPattern somepattern somepath =
case match somepattern (either id id (toText somepath)) of
[] -> mzero
otherwise -> return somepath
greppedls :: FilePath -> Pattern x -> Shell FilePath
greppedls somepath somepattern =
ls somepath >>= filterByPattern somepattern
编辑:这里没有使用不必要的通用MonadPlus
,而是使用特定于海龟的组合器select
进行过滤的实现。 :
filterByPattern :: Pattern x -> FilePath -> Shell FilePath
filterByPattern somepattern somepath =
case match somepattern (either id id (toText somepath)) of
[] -> select [] -- no matches, so filter this path
otherwise -> select [somepath] -- let this path pass
值 foo::Shell a
有点像“a
的列表”。如果我们有一个函数 genlist::a -> Shell b
,它为每个 a
生成一个(可能是空的!)b
列表,我们可以使用 (>>=)
运算符获取 b
的列表:foo >>= genlist
。
编辑#2:标准海龟函数 find
已经使用模式过滤文件。它是递归的并在子目录中搜索。
关于haskell - 如何在 Turtle 中 grep ls 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32284970/