read


read
or learn more

10 Haskell One Liners to Impress Your Friends

Jun 3, 2011

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

  1. 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]

  2. @Adkins

    Thanks, added.

  3. 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.

  4. 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”

  5. anonymous

    any (`isInfixOf` tweet) wordlist

    minimum [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

  6. Gustavs

    Also minimum, maximum.

  7. @all

    Thanks for the tips. Better choices added inline.

  8. 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 :)

  9. 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.

  10. @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.

  11. Impressing friends and supervisors with dollar signs – my main impression of Haskell so far.

  12. Impressing friends and supervisors with dollar signs

    Aren’t they always impressed by dollar signs?

  13. 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.

  14. solrize

    Better use foldl1′ instead of foldl1 and maximum, to avoid space leak :(

  15. 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.

    :)

  16. Yitz

    Even better:

    any (isInfixOf tweet) wordlist

  17. 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)]

  18. 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.

  19. 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]

  20. ps. Sorry but my comment has been stripped down, into the first parens goes a multiply sign :P

  21. 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)]

  22. 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

Reply to “10 Haskell One Liners to Impress Your Friends”