我正在玩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
。这超出了我期望的类似程序的简单性。
有人提到find
函数,它可以以某种方式解决问题。
但是find
相当于find
shell函数,我只是想做ls | grep "foo"
。我不是想解决一个现实生活中的问题(如果我是,我会转而使用bash),而是试图像bash中那样组合简单的砖块。不幸的是,看起来Turtle中的砖块并不容易组合: - (。
答案 0 :(得分:1)
我们可以使用grep
与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
实例结合使用match
代替MonadPlus
进行过滤:
MonadPlus
修改,而不是使用不必要的一般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
,这是一个使用特定于龟的组合器select
进行过滤的实现:
foo :: Shell a
值a
有点像genlist :: a -> Shell b
s"的列表。如果我们有一个函数a
,每个b
生成一个(可能是空的!)b
列表,我们可以使用{{{}获取(>>=)
列表1}} operator:foo >>= genlist
。
编辑#2 :标准海龟功能find
已使用模式过滤文件。它是递归的,并在子目录中进行搜索。
答案 1 :(得分:1)
要从FilePath转换为您使用的文本:
fp :: Format r (FilePath -> r)
以下是一个例子:
format fp ("usr" </> "lib")
有几个问题,所以Gabriel几天前决定更新教程:
https://github.com/Gabriel439/Haskell-Turtle-Library/commit/a2fff2acf912cc7adb2e02671340822feb0e9172
要回答你的(更新的)问题,我能提出的最好的问题是:
format fp <$> ls "." & grep (has "foo") & view
&
扮演的角色是|
。
作为个人笔记,它当然不像ls | grep 'foo'
那么短,但考虑到Haskell是一种打字语言,它仍然相当优雅。
答案 2 :(得分:1)
字面上的答案就是这样一句话:
example =
view (ls "." & fmap (format fp) & grep (prefix "foo") & fmap toText)
惯用的答案是使用find
实用程序
答案 3 :(得分:0)
尝试使用repr
repr :: Show a => a -> Text