
I'm finding a rather unusual problem as I write haskell.. Unlike every other language I've used, large portions of my haskell code are turning out to be general-purpose, reusable code. Fully 20% of the haskell code I've written for git-annex is general purpose. Now, I came out of a decade of perl with maybe 1% reusable code. So I'm sure this is a credit to haskell, and not to me. My problem now is that as I start new projects, I want to have my haskell utility functions available, and copying them around is not ideal. So, put them on hackage. But where, exactly? It already has several grab bag utility libraries. The only one with much traction is MissingH. Using the others makes a program have an unusual dependency, which while only a cabal install away, would make work for distributions that want to package the program. I've ruled out using a couple on that basis. Doesn't encourage me to add another one. My 2000+ lines of reusable code are a grab-bag of generic utility functions. Looking them over (see Appendix), I could try to get portions into existing libraries on hackage, but it's unlikely I'd find a home for most of them, so I'm still left with this problem of what to do. I wonder if the model used for xmonad-contrib, of a big library package, that is very open to additions from contributors, would be helpful here? John, any interest in moving MissingH in this direction? I get the impression it's not otherwise changing much lately, and parts of it are becoming naturally obsolete, maybe this could inject some life into it. Any other thoughts you have on grab-bag utility libraries on hackage also appreciated. ---- Appendix: A sample of a a few of the better functions from my utility library. Some quite generic monadic control functions, few of them truely unique: whenM :: Monad m => m Bool -> m () -> m () -- also >>? unlessM :: Monad m => m Bool -> m () -> m () -- also >>! firstM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a) A module that exports functions conflicting with partial functions in the Prelude, to avoid them being accidentially used. And provides some alternatives (which overlap somewhat with Safe): headMaybe :: [a] -> Maybe a readMaybe :: Read a => String -> Maybe a beginning :: [a] -> [a] Various path manipulation functions such as: dirContains :: FilePath -> FilePath -> Bool dotfile :: FilePath -> Bool absPath :: FilePath -> IO FilePath Other stuff: separate :: (a -> Bool) -> [a] -> ([a], [a]) catchMaybeIO :: IO a -> IO (Maybe a) readSize :: [Unit] -> String -> Maybe ByteSize -- parses "100 kb" etc format :: Format -> Variables -> String findPubKeys :: String -> IO GpgKeyIds boolSystem :: FilePath -> [CommandParam] -> IO Bool withTempFile :: Template -> (FilePath -> Handle -> IO a) -> IO a -- see shy jo