Gabriella439 / turtle

Shell programming, Haskell style

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Interest check: Add a couple convenience functions

devonhollowood opened this issue · comments

So I was playing around with using turtle + ghci as a fully interactive shell the other day (instead of just using it for shell scripts), and I felt it was pretty usable! Mostly it seemed like turtle was just missing a couple small convenience functions based around working with streaming data. These can be demonstrated in the example line:

ls "." >>= stat & sortOn modificationTime & fmap select & join & fmap fileSize & flip fold Fold.sum

Would you have any interest in a pull request adding any of the following convenience functions?

-- Motivation: it would be nice to have a version of (&) which works with functors
-- This way, in the above line, you could write '<&>' instead of '& fmap'
(<&>) = flip fmap
infixl 1 (<&>)
-- Motivation: it would be nice to have a function of type 'Shell [a] -> Shell a'
-- In the above line, this would let you get rid of the '& fmap select & join'
separate = join . fmap select
-- Motivation: in streaming data, it's a little awkward to work with folds because of the argument order.
-- Thus, it would be nice to add a function which is equivalent to reverse fold
reduce = flip Foldl.fold

With the three of these, the original line could be written:

ls "." >>= stat & sortOn modificationTime & separate <&> fileSize & reduce Fold.sum

which I think is a little nicer. For separate, another possibility would be to define a function

separately :: (a -> Shell [b]) -> a -> Shell b
separately f = join . (fmap . fmap) select f

which would let you write separately (sortOn modificationTime) instead.

Let me know what you think! And if you think these are too small / too niche to be useful, I totally understand.

@devonhollowood: Big 👍 for reduce

<&> already exists in Data.Functor, but we can re-export it if you want: http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Functor.html#v:-60--38--62-

I'm not as sure about separate, since it seems to have more limited utility. Also, if you have <&> it takes away some of the need for separate, because you can write foo <&> select & join

Nice, I'll get working on a pull request which adds reduce and re-exports <&>. 👍