10 Haskell One Liners to Impress Your Friends
Following the meme (scala, ruby, clojure, python, f#, coffeescript, c#)
I would truly appreciate feedback from people whom actually know Haskell. As you may notice below, my grasp is not yet strong.
Multiple Each Item in a List by 2
map (*2) [1..10]
Sum a List of Numbers
foldl (+) 0 [1..1000]
-- or better
sum [1..1000]
Verify if Exists in a String
import Data.List
let wordlist = ["monad", "monoid", "Galois", "ghc", "SPJ"]
let tweet = "This is an example tweet talking about SPJ interviewing with Galois"
or $ map (flip isInfixOf tweet) wordlist
-- or better
any (flip isInfixOf tweet) wordlist
Read in a File
fileText <- readFile "data.txt"
let fileLines = lines fileText
-- or better
let fileLines = fmap lines $ readFile "data.txt"
Happy Birthday to You!
mapM_ putStrLn ["Happy Birthday " ++ (if x == 3 then "dear NAME" else "to You") | x <- [1..4]]
Filter list of numbers
let (passed, failed) = partition (>60) [49, 58, 76, 82, 88, 90]
Fetch and Parse an XML web service
this example needs the curl
and xml
packages. see RWH for info on installing them
import Network.Curl
import Text.XML.Light
import Control.Monad
let results = liftM parseXMLDoc $ liftM snd (curlGetString "http://search.twitter.com/search.atom?&q=haskell" [])
-- or better
Control.Applicative
let results = parseXMLDoc . snd <$> curlGetString "http://search.twitter.com/search.atom?&q=haskell" []
Find minimum (or maximum) in a List
foldl1 min [14, 35, -7, 46, 98]
foldl1 max [14, 35, -7, 46, 98]
-- or better
minimum [14, 35, -7, 46, 98]
maximum [14, 35, -7, 46, 98]
Parallel Processing
this example needs the parallel
package.
import Control.Parallel
import Control.Parallel.Strategies
parMap rseq (*2) [1..100]
Prime number generation
let pgen (p:xs) = p : pgen [x|x <- xs, x `mod` p > 0]
take 40 (pgen [2..])
:F
22 Comments, Comment or Ping
Brian Adkins
Regarding summing a list of numbers, it is cool how concise Haskell can be with function invocation, sections, etc., but if you just wanted to sum a list of numbers, I think you’d just use: sum [1..1000]
Jun 3rd, 2011
fogus
@Adkins
Thanks, added.
Jun 3rd, 2011
Neil Brown
For reading in a file, I’d use infix fmap directly to make it a one-liner:
fileLines <- lines readFile “data.txt”
Similarly, I’d use the infix fmap for another one:
parseXMLDoc . snd <$> curlGetString “…” []
Finally, it’s picky, but the code you give isn’t the Sieve of Eratosthenes (see http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf), it’s just a nice simple way to find the primes.
Jun 3rd, 2011
Nicolas T.
You could make this a ‘real’ one-liner (syntax in GHCi, use similar do-notation in a module):
let fileLines = fmap lines $ readFile “/usr/share/dict/words”
Jun 3rd, 2011
anonymous
any (
`isInfixOf`
tweet) wordlistminimum [14, 35, -7, 46, 98] maximum [14, 35, -7, 46, 98]
That isn’t a genuine s.o.e. see for http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
Jun 3rd, 2011
Gustavs
Also
minimum
,maximum
.Jun 3rd, 2011
fogus
@all
Thanks for the tips. Better choices added inline.
Jun 3rd, 2011
semperos
As always, thanks for sharing your explorations into different languages. I’ve been diving back into my Haskell of late as well, nice to reinforce functional programming principles in different languages. Still, nothing compares to Clojure :)
Jun 3rd, 2011
Christopher
I’m a Haskell fan, but I don’t really see how these would impress anyone. I’m sure you could do pretty much all of these as one-liners in Ruby, and (I’m guessing) a few other languages as well. E.g.:
irb(main):003:0> (1..20).map {|x| x*2} => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]
irb(main):009:0> (1..1000).inject{|sum,x| sum + x } => 500500
I’d I wasn’t working, I’d keep going. Maybe someone else can finish for me.
Jun 3rd, 2011
fogus
@Christopher
Someone has already beaten you to it (see the link in my first sentence).
It’s a meme dude; it’s not supposed to make sense.
Jun 3rd, 2011
dasuxullebt
Impressing friends and supervisors with dollar signs – my main impression of Haskell so far.
Jun 3rd, 2011
fogus
Aren’t they always impressed by dollar signs?
Jun 3rd, 2011
Christopher
@fogus: Oh Sorry, it was sort of a hit and run comment.
Here’s maybe a better one liner: Produce a list of pairs of all positive whole numbers from 1 to 10000 that when multiplied by each other equal 10000:
let ubound = 10000 in [ (x,y) | x <- [1..ubound], y <- [1..ubound], x * y == ubound, x <= y]
Produces:
[(1,10000),(2,5000),(4,2500),(5,2000),(8,1250),(10,1000),(16,625),(20,500),(25,400),(40,250),(50,200),(80,125),(100,100)]
You can set ubound to whatever positive whole number you want.
Jun 3rd, 2011
solrize
Better use foldl1′ instead of foldl1 and maximum, to avoid space leak :(
Jun 3rd, 2011
Francis Fish
Ah, so Haskell is less concise than Ruby?
Who’d a thunk it? (sorry – not really true for the more complex examples) I think, though, that Ruby 1.9 nicked ‘take’ and ‘tap’ … are these a Haskell constructs?
Also adding lists of ascending integers.
So, assuming you start from 1
(1..1000).reduce(&:+) # This is Ruby code
==
(1000 * 1001) / 2
(n * (n+1)/2
It uses the average (kind of) and multiplies it by the number of elements.
Summing a whole list doesn’t mean evaluating it.
:)
Jun 4th, 2011
Yitz
Even better:
any (
isInfixOf
tweet) wordlistJun 4th, 2011
Laurie
List comprehensions can be really cool and really powerful too. To take one I used recently,
[(a,b,c) | a <- [1,2,3], b <- [1,2,3], c <- [1,2,3], (a/=b && a/=c && b/=c)]
Generates a list of tuples, containing all unique permutations of the three lists a,b,c, without repetition of any element. So in this case, returns:
[(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)]
Jun 15th, 2011
this
Most of these aren’t that interesting. The primes example is really cool, but I think it doesn’t quite show Haskell’s power when it comes to streams. Something more along the lines a fibonacci stream that shows memoization would really make this cool.
Jul 12th, 2011
Alfredo Di Napoli
Hey guys, what about this non-deterministic computation sponsored by the power of applicative functors?
import Control.Applicative ghci> () <$> [1,2,3] <> [4,5,6] [4,5,6,8,10,12,12,15,18]
Oct 20th, 2011
Alfredo Di Napoli
ps. Sorry but my comment has been stripped down, into the first parens goes a multiply sign :P
Oct 20th, 2011
Johann Visagie
When I first came to Haskell I had a background in both Python and Lisp, so neither a cons nor a list comprehension was new to me. But the way they’re combined in this toy one-liner blew my mind early on:
fib = 1:1:[a+b | (a,b) <- zip fib (tail fib)]
Mar 21st, 2012
Keith
In BASIC, you can add up the numbers from 1 to 1000 in one line, just like this
10 PRINT 1000*(1000+1)/2
It may even run faster than Haskell
May 28th, 2012
Reply to “10 Haskell One Liners to Impress Your Friends”