Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-25 Thread John Goerzen

Hi Joey,

Apologies for such a late reply.  I don't know if others have replied on 
-cafe; it has become too high-volume for me to follow of late.  There 
are several options.  MissingH is one.  I have accepted patches there 
for a long time.  Another is that now that Hackage/Cabal foster easy 
inclusion of small packages, you might want to roll your own.  
(Occasionally I have hesitation about drive-by commits to MissingH 
because I get asked to support the code later at times.)


-- John

On 01/21/2012 02:20 PM, Joey Hess wrote:

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



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-25 Thread John Meacham
That is one of the wonderful things about haskell, most languages have
a negative correlation between codesize and productivity, however with
haskell there is a strong positive correlation. You can re-use so much
that as your code base grows it becomes easier to add new features
rather than harder.

I solve that problem by having a darcs repository for all my utility
modules, then when I want to use them in a project, I just 'darcs
pull' them into the current repository and they appear. as long as a
patch doesn't cross the boundry between the utility modules and the
rest of the codebase I can push changes upstream to the utility
repository from my specific project, or pull in new improvements to
the utility functions. I can also make local modifications to the
utility modules and just not push the local modifications upstream if
needed. The cool thing is that the darcs history has the merged
history of my projects, and tagging with a version number or release
will snapshot both your program and the exact version of the utility
routines used at that time.

The ability to have multiple sibling darcs repositories is a really
powerful feature. quite handy.

I had a similar system before darcs where I used a shared RCS
directory between projects, but that wasn't nearly as seamless or
integrated.

Plus it makes it easier when collaborating, as far as anyone is
concerned, the project is a single darcs repository they can get and
build and create patches for. The fact that behind the scenes it is
actually a collection of repositories spawning patches. modifying
them, and exchanging them in a bizarre parody of bacterial plasmid
exchange* is completely transparent.

John

* stolen prose, I just liked the sound of it.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-24 Thread David Fox
On Mon, Jan 23, 2012 at 1:01 PM, Joey Hess j...@kitenet.net wrote:

    Other stuff:
 
    separate :: (a - Bool) - [a] - ([a], [a])

 Is this partition from Data.List?

 No; it's like break but does not include the separating character in the
 snd list.

I like  let (hd, _ : tl) = break prd lst in...

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-24 Thread David Fox
On Tue, Jan 24, 2012 at 1:00 PM, David Fox dds...@gmail.com wrote:
 On Mon, Jan 23, 2012 at 1:01 PM, Joey Hess j...@kitenet.net wrote:

    Other stuff:
 
    separate :: (a - Bool) - [a] - ([a], [a])

 Is this partition from Data.List?

 No; it's like break but does not include the separating character in the
 snd list.

 I like  let (hd, _ : tl) = break prd lst in...

Oh, wait.  That won't always work. :(

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-24 Thread Chris Wong
 I like  let (hd, _ : tl) = break prd lst in...

 Oh, wait.  That won't always work. :(


second (drop 1) . break prd list?

:)

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-23 Thread Jean-Marie Gaillourdet
Hi,

On 21.01.2012, at 21:20, Joey Hess wrote:

 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.

Personally, I've always been avoiding those grab-bags of functionality like 
MissingH and other libraries. Not because I think they don't provide anything 
useful. But, because their level of maintenance is not clear to me. A rather 
large library of utility functions tends to need many dependencies on other 
hackage packages. That makes the question of maintenance even more important. 

As others have pointed out some of your functions may already exist in some 
widely used package. And other might be easy to be replaced by some idiom. 
Don't underestimate the depth of Haskell and it's well thought libraries. I am 
regularly amazed by finding some new way to combine seemingly trivial functions 
to do some non-trivial task. Every time that happens I can remove some of my 
utility functions.

Therefore, I would reuse my own collection of utility code as a separate 
repository to be included as a sub repository in other projects. Mercurial and 
Git support that very well, I am not sure about darcs' support for that. This 
approach allows you to avoid copypaste reuse and it allows you to evolve your 
personal collection at your speed without worrying for backwards compatibility 
or API changes.

Publishing a library on hackage comes --- at least in an ideal world --- with 
some commitment to document it, keep it compiling and working with a set of 
compiler and library permutations, fix bugs and so on. In short it comes with a 
commitment to maintain it. At least for some time. If you would just like to 
drop some pile of code in hope someone will find it useful. Do that, but 
perhaps there might be better places for that than hackage.

Cheers,
  Jean



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-23 Thread Joey Hess
David Fox wrote:
 I try to create a workflow for this sort of thing.  I create a package
 with a name like set-extra, with one module Data.Set.Extra and an
 alternative Data.Set module that exports both the old Data.Set and the
 symbols in Data.Set.Extra.  Then I email the maintainers of the
 Containers package with a suggestion.  After a while I upload
 set-extra to hackage if I need to use set-extra in another hackage
 package.

Thanks, that's the most helpful hint.
It matches MissingH's use of .Utils modules too.

Jean-Marie Gaillourdet wrote:
 Personally, I've always been avoiding those grab-bags of functionality like
 MissingH and other libraries. Not because I think they don't provide anything
 useful. But, because their level of maintenance is not clear to me. A rather
 large library of utility functions tends to need many dependencies on other
 hackage packages. That makes the question of maintenance even more important.

It's not clear to me either. I used MissingH starting out because I
personally know and trust John and/or he cowrote RWH.
Don't know that I would have otherwise.

(And I only use Data.String.Utils, System.Cmd.Utils, and Data.Bits.Utils
from it.)

 As others have pointed out some of your functions may already exist in some
 widely used package. And other might be easy to be replaced by some idiom. 
 Don't
 underestimate the depth of Haskell and it's well thought libraries. I am
 regularly amazed by finding some new way to combine seemingly trivial 
 functions
 to do some non-trivial task. Every time that happens I can remove some of my
 utility functions.

Well, this is certianly true, on the other hand then you end up with a
pattern of repeatedly combining some trivial functions in a certian way,
and it then makes sense to formalize that. It's better to have `fromMaybe`
than to repeatedly use `id` with `maybe`.

Tristan Ravitch wrote:
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)
 
 IfElse 
 (http://hackage.haskell.org/packages/archive/IfElse/0.85/doc/html/Control-Monad-IfElse.html)
 has a few of these.

whenM is in a dozen packages, the others fewer but scattered here and
there. I also found ? and ! somewhere on hackage once but not sure
where.

Various path manipulation functions such as:
absPath :: FilePath - IO FilePath
 
 Is this different from canonicalizePath in directory?

Yes; it doesn't require the path to exist.

Other stuff:
 
separate :: (a - Bool) - [a] - ([a], [a])
 
 Is this partition from Data.List?

No; it's like break but does not include the separating character in the
snd list.

format :: Format - Variables - String
 
 This looks like it might be similar to HStringTemplate

This particular format allows for things like ${foo} ${bar;10} ${baz;-10}\n
so it's sort of printf like, but not entirely.

withTempFile :: Template - (FilePath - Handle - IO a) - IO a
 
 temporary 
 (http://hackage.haskell.org/packages/archive/temporary/1.1.2.3/doc/html/System-IO-Temp.html)
 has a few variants of this one

Indeed, however all its functions can fail if getTemporaryDirectory
fails; this one puts the temp file in . in that case.

Simon Hengel wrote:
headMaybe :: [a] - Maybe a
 
 Is this the same as Data.Maybe.maybeToList?

Rather listToMaybe.. it is the same as that in fact.
Though I also have a lastMaybe that does not have an equivilant in Data.Maybe.

readMaybe :: Read a = String - Maybe a
 
 This has been added to base recently [1].

Great! Although there are multiple ways to choose to implement this. 
I found it useful to make it succeed even if not all the string was
consumed, or when there are multiple valid results. I've renamed
mine readish.

-- 
eee shy jo


signature.asc
Description: Digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-22 Thread David Fox
I try to create a workflow for this sort of thing.  I create a package
with a name like set-extra, with one module Data.Set.Extra and an
alternative Data.Set module that exports both the old Data.Set and the
symbols in Data.Set.Extra.  Then I email the maintainers of the
Containers package with a suggestion.  After a while I upload
set-extra to hackage if I need to use set-extra in another hackage
package.

On Sat, Jan 21, 2012 at 12:20 PM, Joey Hess j...@kitenet.net wrote:
 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

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] where to put general-purpose utility functions

2012-01-21 Thread Joey Hess
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


signature.asc
Description: Digital signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-21 Thread Mike Burns
On 2012-01-21 16.20.25 -0400, Joey Hess wrote:
 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?

Instead of putting all of them in one package, how about you group them
into multiple relevant packages. That way we can search for them more
easily, have smaller, more meaningful imports, and so on. Sometimes they
may make sense as pull requests against other packages, instead.

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-21 Thread Tristan Ravitch
You might find many of these on hackage in various forms already.. it
might be easier to just depend on some of those libraries.

On Sat, Jan 21, 2012 at 04:20:25PM -0400, Joey Hess wrote:

   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)

IfElse 
(http://hackage.haskell.org/packages/archive/IfElse/0.85/doc/html/Control-Monad-IfElse.html)
has a few of these.

   Various path manipulation functions such as:
   absPath :: FilePath - IO FilePath

Is this different from canonicalizePath in directory?

   Other stuff:

   separate :: (a - Bool) - [a] - ([a], [a])

Is this partition from Data.List?

   format :: Format - Variables - String

This looks like it might be similar to HStringTemplate

   withTempFile :: Template - (FilePath - Handle - IO a) - IO a

temporary 
(http://hackage.haskell.org/packages/archive/temporary/1.1.2.3/doc/html/System-IO-Temp.html)
has a few variants of this one


pgpJEP0MrWorv.pgp
Description: PGP signature
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-21 Thread Simon Hengel
   headMaybe :: [a] - Maybe a

Is this the same as Data.Maybe.maybeToList?

   readMaybe :: Read a = String - Maybe a

This has been added to base recently [1].

Cheers,
Simon

[1] 
https://github.com/ghc/packages-base/commit/0e1a02b96cfd03b8488e3ff4ce232466d6d5ca77

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-21 Thread Christoph Breitkopf
One thing I found useful when looking if a function already exists under a
different name is to use Hayoo to search for the type, i.e.:

http://holumbus.fh-wedel.de/hayoo/hayoo.html#0:(a%20-%3E%20Bool)%20-%3E%20%5Ba%5D%20-%3E%20(%5Ba%5D%2C%5Ba%5D)

- Chris
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-21 Thread Thiago Negri
There is also Hoogle, pretty equivalent I guess.

http://www.haskell.org/hoogle/

Thiago.

2012/1/21 Christoph Breitkopf chbreitk...@googlemail.com:
 One thing I found useful when looking if a function already exists under a
 different name is to use Hayoo to search for the type, i.e.:

 http://holumbus.fh-wedel.de/hayoo/hayoo.html#0:(a%20-%3E%20Bool)%20-%3E%20%5Ba%5D%20-%3E%20(%5Ba%5D%2C%5Ba%5D)

 - Chris

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] where to put general-purpose utility functions

2012-01-21 Thread Christoph Breitkopf
On Sat, Jan 21, 2012 at 11:08 PM, Christoph Breitkopf 
chbreitk...@googlemail.com wrote:

 One thing I found useful when looking if a function already exists under a
 different name is to use Hayoo to search for the type, i.e.:


 Uh - please ignore the bogus link - I had blindly assumed that it would
show my search results.

Just use http://holumbus.fh-wedel.de/hayoo/hayoo.html to search for (a -
Bool) - [a] - ([a],[a]), for eaxample, and it will find break, span,
partiion, etc.

- Chris
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe