The issue is that, if you want to simulate both "grep" and "grep -r", you need to different functions, or you need to have your "grep" function accept a record of parameters.
I'm not good enough haskell programmer, but there is possible solution (records as you mentioned).
import Prelude hiding ((-))
data Grep = Grep {isRecursive :: Bool, maxCount :: Maybe Int} --etc
deriving (Show)
grep = Grep False Nothing
--short pseudonim
r :: Grep -> Grep
r command = command{isRecursive = True}
m :: Int -> Grep -> Grep
m num command = command{maxCount = Just num}
(-) :: a -> (a -> a) -> a
(-) command flag = flag command
ourGrep = grep -m 50 -r
main = print ourGrep -- > Grep {isRecursive = True, maxCount = Just 50}
--then we should write monad which execute that data
Yes, that's exactly what I wouldn't want to type. Also, your record is going to blow up in the likely case another utility uses a recursive flag, because of Haskell's pervasive namespacing problems.
in a typesafe way. It just probably wouldn't be worth the complexity. It also probably couldn't be a straight `IO` action then, which was a design constraint of Gabriel's.
Actually, you can do `grep -r` by just combining `grep` and `lstree`. Here's an example:
example = do
file <- lstree "some/dir"
True <- liftIO (testfile file)
grep "Some pattern" (input file)
This is an example of how most of Bash's option heavy ecosystem is an outgrowth of Bash's limitation as a language (individual commands accumulate flags to work around functionality difficult to implement within the Host language). I think having a decent host language decreases the need for so many configuration knobs for every command.
You're right to some extent, but I think many of these 'knobs' have a good reason to exist (--dry-run, -a, -z for rsync for instance) and cannot be usefully, or at all, replaced by more composability. And attempting to implement support for them will run against the limitations of Haskell's syntax.
Something like OCaml would be better suited, since polymorphic variants, named and default arguments give a lot more flexibility, though the fact that shell commands happily return different outputs depending on their options would still be an issue.
I saw those as regular parser that returns text but not just grep wrapper. Yes It has function named 'grep', but its not grep wrapper. It looks like `lstree` could be combined with `grep` function for emulate `grep -r`.
I guess you wouldn't, you'd have a sort function afterwards.
...for Unix' insistence on composability, the shell tools are often unnecessarily monolithic, probably because that's the only sane way if the only type you have in interconnect is `string`.
Sure, but consider the common case of wanting the most recent file/directory in a directory. This would be something like "ls -t|head -n 1". It's pretty convenient, AND your ls function still returns only file and directory names, no additional information.
Here, you'd need to either parametrize the return type of ls to get simple strings (which is what you want most of time) or additional metadata, or alternatively to have different ls commands.