Hacker Newsnew | past | comments | ask | show | jobs | submitlogin



That's not the issue.

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.


It probably wouldn't be too hard to do something like

    grep "foo"
      & "recursive" <~ True
      & "maxCount"  <~ 100
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.


Unix has

     find . -exec grep $pattern {} \;

but `grep -r` is easier to write.


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`.


Take lstree then. How would you give it an option giving the kind of ordering you want?


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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: