why use haskell?
DESCRIPTION
A few times now, I've been asked, "Haskell looks cool, but what should I use it for?" This presentation attempts to showcase some of the unique parts of Haskell in order to make it easier to understand why you might be interested in learning it.TRANSCRIPT
Why use Haskell?
Haskell was made by some really smart guys (with PhDs).
“- Learn You a Haskell
Haskell is a purely functional programming language.
Easier to Understand
Ruby Haskelldef plan_name @user.account.plan.name end
planName :: User -> String planName = name . plan . account
Ruby Haskelldef slugs(projects) projects. map { |project| project. name. downcase }. uniq end
slugs :: [Project] -> [String] slugs = uniq . map (downcase . projectName)
Less Buggy
• No distinction between pass by reference, pass by value.
• Don’t need to worry about dup, freeze, and friends.
Easier to Write
Ruby Haskelldef combine(elements, new_element) existing_index = elements. find_index { |existing| existing. combinable?(new_element) } if existing_index existing_element = elements. delete_at(existing_index) elements << existing_element. merge(new_element) else elements << new_element end end
combine :: Combinable a => Seq a -> a -> Seq a combine xs x = case existingIndex of Just i -> adjust (combine x) i xs Nothing -> x <| xs where existingIndex = findIndexL (similar x) xs
Paralellization
• Ruby: Thread, Mutex, Semaphore, Locking, Contention
• Haskell: par, pseq
Haskell is lazy.
Clearer Code
Ruby HaskellletterValues :: Int -> [(Char, Int)] letterValues start = zip ['a'..'z'] [start..] !main :: IO () main = do (start:_) <- getArgs mapM_ print $ letterValues $ read start
def letter_values(start) letters = 'a'..'z' letters. zip(start..(letters.count)) end !def main start = ARGV[0].to_i puts letter_values(start). map(&:inspect) end
Ruby HaskellletterValues :: Int -> [(Char, Int)] letterValues start = zip ['a'..'z'] [start..] !main :: IO () main = do (start:_) <- getArgs mapM_ print $ letterValues $ read start
def letter_values(start) ('a'..'z'). each_with_index do |letter, i| [letter, i + start] end end !def main start = ARGV[0].to_i puts letter_values(start). map(&:inspect) end
Better Memory Usage
Ruby HaskellwordsPerLine :: String -> Float wordsPerLine = mean . map (length . words) . lines !main :: IO () main = print . wordsPerLine =<< getContents
def words_per_line(string) string. split("\n"). map { |line| line. split(' '). size }. average end !def main puts words_per_line(STDIN.read) end
Ruby HaskellwordsPerLine :: String -> Float wordsPerLine = mean . map (length . words) . lines !main :: IO () main = print . wordsPerLine =<< getContents
def words_per_line(io) io. each_line. map { |line| line. split(' '). size }. average end !def main puts words_per_line(STDIN) end
Haskell is statically typed.
Clarity
Prelude> :type elemsWithIndex elemsWithIndex :: [b] -> [(b, Int)]
Speed
Type Safety
Ruby Haskellclass Square def initialize(length) @length = length end ! def area @length * @length end end !class Rectangle def initialize(width, length) @width, @length = width, length end ! def area @width * @length end end
class Shape a where area :: a -> Int !data Square = Square Int instance Shape Square where area (Square length) = length * length !data Rectangle = Rectangle Int Int instance Shape Rectangle where area (Rectangle width length) = width * length
Ruby Haskelldef plan_name(user) if user.account user.account.plan.name end end
planName :: User -> String planName user = (name . plan) <$> account user
Ruby Haskelldef plan_name(user) user.account.plan.name end
planName :: User -> String planName user = name $ plan $ account user
Airbrake Error Compile Error
Haskell is fun, safe, and fast.
• Clearer code with types and less boilerplate.
• Fewer bugs with type safety and immutable objects.
• Compiled code runs quickly, even in parallel.
Getting Started
brew install haskell-platform
Learn You a Haskell http://learnyouahaskell.com