3

我正在和Turtle一起玩,我面临以下问题。

我想做类似的事情(在外壳中)

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,它相当于findshell 函数,我只是想这样做ls | grep "foo"。我不是在尝试解决现实生活中的问题(如果我是,我会改用 bash),而是尝试像在 bash 中那样组合简单的积木。不幸的是,Turtle 中的积木似乎并不那么容易组合:-(。

4

4 回答 4

1

代替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

编辑:这里没有使用不必要的 general 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有点像“ as 列表”。如果我们有一个函数genlist :: a -> Shell b,它为每个a生成一个(可能是空的!)s 列表,我们可以使用运算符b获得一个 s 列表:。b(>>=)foo >>= genlist

编辑#2:标准的海龟函数find已经使用模式过滤文件。它是递归的并在子目录中搜索。

于 2015-08-29T12:01:49.370 回答
1

字面上的答案是这个单行:

example =
    view (ls "." & fmap (format fp) & grep (prefix "foo") & fmap toText)

惯用的答案是使用该find实用程序

于 2016-01-29T18:09:15.160 回答
1

要将 FilePath 转换为 Text,请使用:

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 是一种类型化语言,它当然没有那么短,但仍然相当优雅。

于 2015-08-29T13:45:40.317 回答
0

尝试使用repr

repr :: Show a => a -> Text
于 2015-08-29T10:27:49.297 回答