unfoldr [ANN: HLint 1.2]

Neil Mitchell wrote:
Hi Andrew,
HLint will automatically detect if you should have used a map, a foldr or a foldl and suggest how to change your code. In the GHC, darcs and Hoogle code bases there are no obvious map-like functions, which is a good sign :-)
...What an intriguing idea. Clearly I'm going to have to play with this sometime soon.
Does it suggest unfoldr too?
No, but it could do in the future - I never use unfold's in my code, so am not really familiar with them. But I will look into them, do you have any examples where it should suggest unfoldr so I can play with them?
Off the top of my head, try this: convert b 0 = [] convert b n = n `mod` b : convert b (n `div` b) (Takes a number and yields the radix-B representation of it. Backwards.) convert b = unfoldr (\n -> if n > 0 then Just (n `mod` b, n `div` b) else Nothing) It's also useful for converting a data structure into a list: heap_to_list = unfoldr (\h -> if heap_empty h then Nothing else Just (heap_top h, heap_delete_top h)) Those are the major uses I'm aware of. I'm sure somebody else will think of others. (IIRC, unstream is implemented as an unfold...?)

On Mon, 12 Jan 2009, Andrew Coppin wrote:
Off the top of my head, try this:
convert b 0 = [] convert b n = n `mod` b : convert b (n `div` b)
(Takes a number and yields the radix-B representation of it. Backwards.)
convert b = unfoldr (\n -> if n > 0 then Just (n `mod` b, n `div` b) else Nothing)
I have the nice function 'toMaybe' which simplifies this to: unfoldr (\n -> toMaybe (n>0) (n `mod` b, n `div` b)) Maybe HLint can also suggest non-base functions? ;-) http://hackage.haskell.org/packages/archive/utility-ht/0.0.2/doc/html/Data-M...

On Mon, 12 Jan 2009 21:04:35 +0100 (CET)
Henning Thielemann
On Mon, 12 Jan 2009, Andrew Coppin wrote:
Off the top of my head, try this:
convert b 0 = [] convert b n = n `mod` b : convert b (n `div` b)
(Takes a number and yields the radix-B representation of it. Backwards.)
convert b = unfoldr (\n -> if n > 0 then Just (n `mod` b, n `div` b) else Nothing)
I have the nice function 'toMaybe' which simplifies this to: unfoldr (\n -> toMaybe (n>0) (n `mod` b, n `div` b))
I would use the more general idiom: unfoldr (\n -> guard (n > 0) >> return (n `mod` b, n `div` b)) -- Robin

Robin Green wrote:
On Mon, 12 Jan 2009 21:04:35 +0100 (CET) Henning Thielemann
wrote: On Mon, 12 Jan 2009, Andrew Coppin wrote:
convert b = unfoldr (\n -> if n > 0 then Just (n `mod` b, n `div` b) else Nothing)
I have the nice function 'toMaybe' which simplifies this to: unfoldr (\n -> toMaybe (n>0) (n `mod` b, n `div` b))
I would use the more general idiom:
unfoldr (\n -> guard (n > 0) >> return (n `mod` b, n `div` b)
One of the wonderful things about Haskell is that almost any time anybody posts code, at least one person will think up an alternative but equivilent way of achieving the same goal - sometimes by radically different steps. Maybe we should have a name for this effect?

2009/1/13 Andrew Coppin
One of the wonderful things about Haskell is that almost any time anybody posts code, at least one person will think up an alternative but equivilent way of achieving the same goal - sometimes by radically different steps.
Maybe we should have a name for this effect?
Confusion.

Colin Adams wrote:
2009/1/13 Andrew Coppin
: One of the wonderful things about Haskell is that almost any time anybody posts code, at least one person will think up an alternative but equivilent way of achieving the same goal - sometimes by radically different steps.
Maybe we should have a name for this effect?
Confusion.
This is a worthy addition to the Humour page, IMHO... :-D

Colin Adams wrote:
2009/1/13 Andrew Coppin
: One of the wonderful things about Haskell is that almost any time anybody posts code, at least one person will think up an alternative but equivilent way of achieving the same goal - sometimes by radically different steps.
Maybe we should have a name for this effect?
Confusion.
Ah, so Haskell is completely reducible to Perl then? ;-)

"Colin Adams"
One of the wonderful things about Haskell is that almost any time anybody posts code, at least one person will think up an alternative but equivilent way of achieving the same goal - sometimes by radically different steps.
Maybe we should have a name for this effect?
Confusion.
Golfusion? -k -- If I haven't seen further, it is by standing in the footprints of giants

On Mon, 2009-01-12 at 21:48 +0000, Robin Green wrote:
convert b = unfoldr (\n -> if n > 0 then Just (n `mod` b, n `div` b) else Nothing)
I have the nice function 'toMaybe' which simplifies this to: unfoldr (\n -> toMaybe (n>0) (n `mod` b, n `div` b))
I would use the more general idiom:
unfoldr (\n -> guard (n > 0) >> return (n `mod` b, n `div` b))
I have the equivalent in my ‘useful functions’:
ifM p x = if p then return x else mzero

Hi
convert b 0 = [] convert b n = n `mod` b : convert b (n `div` b)
convert b = unfoldr (\n -> if n > 0 then Just (n `mod` b, n `div` b) else Nothing)
To my untrained eyes the second looks more complex... It can't be implemented in the HLint list recursion functions I've got at the moment since they first search for a pattern-match on []/(:) on the left to start the process, but maybe one day.
I have the nice function 'toMaybe' which simplifies this to: unfoldr (\n -> toMaybe (n>0) (n `mod` b, n `div` b))
Maybe HLint can also suggest non-base functions? ;-)
Yes, sure - but not by default. See http://code.google.com/p/ndmitchell/issues/detail?id=126 The idea is that if someone wants to maintain a separate Hints file, say HackageHints.hs, then an individual user can decide to add import HackageHints to their Hints.hs and use the additional hints, which may require arbitrary Haskell libraries. Thanks Neil

Andrew Coppin wrote:
Does it suggest unfoldr too?
I think Neil's idea to have this customizable is a good one. It's often a matter of taste. I would rarely want to use unfoldr, and I wouldn't want HList to bother me about it. Instead, I prefer to use iterate for both of Andrew's examples:
convert b 0 = [] convert b n = n `mod` b : convert b (n `div` b)
convert b = unfoldr (\n -> if n > 0 then Just (n `mod` b, n `div` b) else Nothing)
convert b = map (`mod` b) . takeWhile (> 0) . iterate (`div` b)
heap_to_list = unfoldr (\h -> if heap_empty h then Nothing else Just (heap_top h, heap_delete_top h))
heap_to_list = map heap_top . takeWhile (not . heap_empty) . iterate heap_delete_top Here is one case where I actually do use unfoldr: -- Mine free-form user input for occurrences of a data type readMany = unfoldr $ listToMaybe . concatMap reads . tails ghci> readMany "The numbers are 3, 7, and 42." :: [Int] [3,7,42] But I don't believe HLint should be expected to come up with something like that. It's quite rare. Regards, Yitz
participants (9)
-
Andrew Coppin
-
Colin Adams
-
George Pollard
-
Henning Thielemann
-
John Goerzen
-
Ketil Malde
-
Neil Mitchell
-
Robin Green
-
Yitzchak Gale