Description from the DevBeat 2013 site
Wednesday, November 13, 2013, Master Class: Haskell
Nearly everyone who learns Haskell seems to turn into a raving Haskell fan. They say things like “I can write 80% less code and still get native multicore performance” and “I can easily understand code I wrote two years ago” and “my programs often work the first time they compile" and “now when I have to use Java, I feel like I’m being punished.” What makes Haskell so productive, fast, maintainable, and bug-free? And can you learn it without your head exploding? In this talk Aaron, a raving fan himself, will walk you through the basics of Haskell. You’ll see how to use interactive Haskell tools to become productive and learn quickly. By the end of the talk you will know what Haskell’s about AND you’ll be ready to use free online Haskell resources to easily learn more.
In addition to this article, I used some code in the IDE during this lecture. The IDE is browser-based; get your account here so you can follow along.
Credits: In preparing this material I made use of contributions to the School of Haskell by Yann Esposito, Bartosz Milewski, and Brent Yorgey.
- Purely functional, no side effects
- Powerful type system
- Use of monads
- Fast time to initial working version
- Maintainability, abstraction, reuse
- Low bugs, mostly caught at compile time
- Native C++ like performance
- Fundamental data analysis for Web and Mobile
- Unique/competitive [big] data analysis
- New York Times
- Financial analysis
- Standard Chartered Bank
- OTAS Technologies
- Scientific modeling
- Adding headroom to Ruby/Python projects
- low punctuation, significant indentation
- function call syntax
add a b = a + b main = do print (add 6 5) print (6 `add` 5)
- Operators like
+are just functions with names made of symbol characters
- Defaults to infix notation for traditional nice syntax
- !#$%&*+./<=>?@\^|-~ (and non-ascii Unicode symbol or punctuation)
a !@ b = a + b a ∆ b = a - b main = do print (6 !@ 5) print ((!@) 6 5) print (6 ∆ 5)
a $ b c d esugar for
a (b c d e)
main = do print (5 + 2 * 3) print $ 5 + 2 * 3
(a . b) cmeans
a (b c)
double x = x + x sixteenTimes = double . double . double . double main = do print $ double 2 print $ (double . double . double) 2 print $ sixteenTimes 2
Type definitions can be omitted & deduced
Numbers: Integer Int Float Double Complex and more, all in type class Num
import Data.Ratio -- defines type Rational in type class Num oneThird = 1 % 3 fiveEighths = 5 % 8 main = print (2 * oneThird * fiveEighths)
- Lists [a,b,c] or [n1,n2..nn]
- Infinite lists (note: lazy evaluation) [n1,n2..]
- List comprehensions
ns = [1..20] evens = [2,4..20] allPos = [1,2..] favoritePos = [x | x <- allPos, x `mod` 10 == 0] main = do print $ take 5 ns print $ take 5 allPos print $ take 5 favoritePos
- Huge set of utility functions
a = (5,2) b = (10,1) items = a : (replicate 3 b) main = do print items
typecreates synonyms of existing types
datacreates new types
data Breakfast = Cereal | Yogurt | Egg Integer deriving (Show, Eq) a = Yogurt b = Egg 3 moreEgg (Egg n) = Egg (n+1) moreEgg x = x -- Adding an egg to anything else has no effect addEggs k (Egg n) = if k < 1 then Egg n else addEggs (k-1) (Egg (n+1)) addEggs k x = x main = do print a print b print $ moreEgg a print $ moreEgg b print $ (moreEgg . moreEgg . moreEgg) b print $ addEggs 14 (Egg 2) print $ (map moreEgg) [Yogurt, Yogurt, Egg 4, Cereal, Egg 1]
- constructors are functions
Just a(where a is some type) or
import Data.Maybe x = Just 5 y = Nothing safeAdd :: Maybe Int -> Maybe Int -> Maybe Int safeAdd (Just a) (Just b) = Just (a+b) safeAdd _ _ = Nothing main = do print $ safeAdd x y print $ safeAdd (Just 2) (Just 5)
Right b(e.g. use Left String for errors, Right Int for answers)
- Record syntax, accessors
- Recursive types
derivingis like inheritance
- Function types
- Styles of handling inputs
tryDivi :: Double -> Double -> Maybe Double tryDivi a b = if b==0 then Nothing else Just (a / b) -- conditional tryDivide :: Double -> Double -> Maybe Double tryDivide _ 0 = Nothing -- pattern matching trydivide a b = Just (a / b) tryDiv :: Double -> Double -> Maybe Double tryDiv a b | b==0 = Nothing -- guards | otherwise = Just (a / b)
Eliminating final argument ("eta reduction")
inc x = x + 1 inc' = (+ 1) -- final arg on left = final arg on right add a b = a + b addFive = add 5 -- partial evaluation returns a function: "Currying" inc'' = add 1 main = do print $ inc' 10 print $ addFive 10
Function as parameter
increment = (+ 1) doTwice f x = f (f x) main = do print $ increment 5 print $ doTwice increment 5 print $ map increment [1..9]
Lambda (written as backslash) for anonymous functions
main = do print $ map (\x -> x * x + 1) [1..9]
Recursion, tail recursion
-- Apply a function to every list element using recursion -- Works for a list of any type a and returns a list of any type b -- assuming that f is a function that takes an a and returns a b -- Note: this trivial function is equivalent to map apply :: (a -> b) -> [a] -> [b] apply f  =  apply f [x] = [f x] apply f (x : xs) = (f x) : (apply f xs) main = do print $ apply (* 2) [1..5] print $ apply (* 2)  print $ apply (\x -> x * x) [1..5] print $ take 20 $ apply show [10,20..]
foldreduces a whole list to a single result
- Important to choose a variant that doesn't use huge temporary memory
- A burrito: a value-added container for oblivious but valuable contents
- A typeclass (keyword
class) is like an
Monadis a typeclass using
- Wrap a type into a value-added type
- Used for sequencing and passing on value-added state
- Uses the IO () monad
dosyntax for sequences of monads looks like imperative code
- Separates side-effectful code from purely functional code
(putStrLn . show)
- Simple Sudoku solver (Open in IDE)
- Running in the IDE / Console
- Application Server: easily deploy and manage
- "Gravity Fun" physics simulation
- JSON to communicate with server-based physics model
- Run in the IDE / Browser tab
- Application Server: easily deploy and manage
- Native high-performance threads
- Lack of side effects means safe concurrency
- Software Transactional Memory
- Parallel Haskell
- Cloud Haskell
- Get started trivially:
import Control.Parallel.Strategies slowFib x = if x<3 then 1 else (slowFib (x-1)) + (slowFib (x-2)) inputs = [17, 7, 15, 5, 18, 2, 15, 3, 24] main = do print $ map slowFib inputs -- sequential print $ (parMap rpar) slowFib inputs -- parallel
- Yesod or Happstack to make a Web server
- Database access
If you prefer your learning in book form, the text Learn You a Haskell for Great Good is a good choice and so is Real World Haskell. These sites include the full text of the the books online, as well as links to order the e-book or dead-tree version.
On-site Haskell classes for companies are available from FP Complete and from Well-Typed.
Online headquarters for the Haskell open-source community is haskell.org. The site includes a wiki of diverse Haskell information, and links for downloading open-source Haskell tools.
The main online database of Haskell packages is Hackage. There is a compatibility-checked subset called Stackage, also used in FP Haskell Center.
The main online help repository for Haskell is Hoogle. It is available as a website and within FP Haskell Center.
The biggest Haskell conference is the annual ACM SIGPLAN Haskell Symposium.
Here is a video introducing Haskell at an overview/manager level. Show it to your manager!
Haskell is used commercially in various industries including finance, biotechnology, defense, and a range of Internet companies.
Detailed commercial case studies are published by FP Complete.
Another interesting case study about Haskell usage at the New York Times.
The Haskell in Industry Wiki page lists further examples.
Haskell Talks is a recently started series of video interviews with Haskell users.
Aaron Contorer is CEO and founder of FP Complete, specializing in Haskell tools and services. His longer bio is here.
Dr. Dobb's Journal recently published his article In Praise of Haskell.
(c) 2013 FP Complete Corporation.