From Ruby to Haskell (Kansai Yami RubyKaigi)

38
From Ruby to Haskell Kansai Yamiruby Kaigi Nov 13, 2011 Tatsuhiro Ujihisa Sunday, November 13, 2011

description

for http://cotocoto.jp/event/46352

Transcript of From Ruby to Haskell (Kansai Yami RubyKaigi)

Page 1: From Ruby to Haskell (Kansai Yami RubyKaigi)

From Ruby to Haskell Kansai Yamiruby Kaigi

Nov 13, 2011Tatsuhiro Ujihisa

Sunday, November 13, 2011

Page 2: From Ruby to Haskell (Kansai Yami RubyKaigi)

Agenda• Haskell (introduction)

• Haskell (for beginners)

• Self-introduction

• Haskell (for average people)

• Haskell (for pro)

Sunday, November 13, 2011

Page 3: From Ruby to Haskell (Kansai Yami RubyKaigi)

Haskell (1/3)

Sunday, November 13, 2011

Page 4: From Ruby to Haskell (Kansai Yami RubyKaigi)

Haskell• Programming language

• 1990~

• GHC

Sunday, November 13, 2011

Page 5: From Ruby to Haskell (Kansai Yami RubyKaigi)

Haskell• Strong static-typed

• Interpreter & native compiler

• Lazy evaluation

main = print "hello"

Sunday, November 13, 2011

Page 6: From Ruby to Haskell (Kansai Yami RubyKaigi)

FizzBuzz in Ruby1 (1..100).each do |i|2 puts i % 15 == 0 ? 'FizzBuzz' :3 i % 5 == 0 ? 'Buzz' :4 i % 3 == 0 ? 'Fizz' :5 i6 end

1 def main 2 puts fizzbuzz 3 end 4 5 def fizzbuzz 6 (1..100).map {|i| 7 i % 15 == 0 ? 'FizzBuzz' : 8 i % 5 == 0 ? 'Buzz' : 9 i % 3 == 0 ? 'Fizz' :10 i11 }12 end13 14 main

Sunday, November 13, 2011

Page 7: From Ruby to Haskell (Kansai Yami RubyKaigi)

FizzBuzz in Ruby 1 def main 2 puts fizzbuzz 3 end 4 5 def fizzbuzz 6 (1..100).map {|i| 7 i % 15 == 0 ? 'FizzBuzz' : 8 i % 5 == 0 ? 'Buzz' : 9 i % 3 == 0 ? 'Fizz' :10 i11 }12 end13 14 main

1 def main 2 puts fizzbuzz 3 end 4 5 def fizzbuzz 6 f = -> i do 7 i % 15 == 0 ? 'FizzBuzz' : 8 i % 5 == 0 ? 'Buzz' : 9 i % 3 == 0 ? 'Fizz' :10 i11 end12 (1..100).map &f13 end14 15 main

Sunday, November 13, 2011

Page 8: From Ruby to Haskell (Kansai Yami RubyKaigi)

FizzBuzz in Haskell 1 def main 2 puts fizzbuzz 3 end 4 5 def fizzbuzz 6 f = -> i do 7 i % 15 == 0 ? 'FizzBuzz' : 8 i % 5 == 0 ? 'Buzz' : 9 i % 3 == 0 ? 'Fizz' :10 i11 end12 (1..100).map &f13 end14 15 main

1 main = print fizzbuzz2 3 fizzbuzz = map f [1..100]4 where f n5 | n `rem` 15 == 0 = "FizzBuzz"6 | n `rem` 5 == 0 = "Buzz"7 | n `rem` 3 == 0 = "Fizz"8 | otherwise = show n

Sunday, November 13, 2011

Page 9: From Ruby to Haskell (Kansai Yami RubyKaigi)

Haskell (2/3)

Sunday, November 13, 2011

Page 10: From Ruby to Haskell (Kansai Yami RubyKaigi)

1 main = print (a + b)2 a = 13 b = 2

1 main = print (a + b)2 a = 1 :: Int3 b :: Int4 b = 2

1 main = print (a + b)2 a = 1 :: Int3 b :: Int4 b = 2.1

1 a.hs:4:5:2 No instance for (Fractional Int)3 arising from the literal `2.1'4 Possible fix: add an instance declaration for (Fractional Int)5 In the expression: 2.16 In an equation for `b': b = 2.17

Sunday, November 13, 2011

Page 11: From Ruby to Haskell (Kansai Yami RubyKaigi)

Type and type-class• type (in Haskell) =~ class (in Ruby)

• type class (in Haskell) =~module (in Ruby)

• Int type =~ Fixnum class

• Num type-class =~ Numeric module

Sunday, November 13, 2011

Page 12: From Ruby to Haskell (Kansai Yami RubyKaigi)

Literals• Ruby: only one type

• 1 (always Fixnum)

• "hello" (always String)

• Haskell: compiler infers

• 1 (Int? Integer? Float? Rational?)

• "a" (String? Test? ByteString?)

Sunday, November 13, 2011

Page 13: From Ruby to Haskell (Kansai Yami RubyKaigi)

1 main = print (a + b)2 a = 1 :: Int3 b = 2.1

1 main = print (a + b)2 a = 13 b = 2.1

error

ok

b and (a+b) can be Float, Double or Rational

Sunday, November 13, 2011

Page 14: From Ruby to Haskell (Kansai Yami RubyKaigi)

Lists• [1, 2, 3]

• 1 : 2 : 3 : []

• ["a", "b", "c"]

• [1, 2, "a"] ERROR

Sunday, November 13, 2011

Page 15: From Ruby to Haskell (Kansai Yami RubyKaigi)

Functions• call

• f a

• g a b

• define

• f a = something

• g a b = something

Sunday, November 13, 2011

Page 16: From Ruby to Haskell (Kansai Yami RubyKaigi)

Operators• call

• 1 + 2

• (+) 1 2

• 1 `g` 2

• define

• a + b = something

Sunday, November 13, 2011

Page 17: From Ruby to Haskell (Kansai Yami RubyKaigi)

Interesting operators• $

• f (g (h a b)))

• f $ g $ h a b

• a : b : c : [] == [a, b, c]

• expected @=# actual

Sunday, November 13, 2011

Page 18: From Ruby to Haskell (Kansai Yami RubyKaigi)

Combining actionsmain = print [1, 2, 3] >> print "hi"

1 main = do2 print [1, 2, 3]3 print "hi"

main = do { print [1, 2, 3]; print "hi" }

Sunday, November 13, 2011

Page 19: From Ruby to Haskell (Kansai Yami RubyKaigi)

only for side effect

• Ruby

• puts 'hi'puts 'yo'

• puts 'hi'; puts 'yo'• Haskell

• do putStrLn "hi" putStrLn "yo"

• putStrLn "hi" >> putStrLn "yo"Sunday, November 13, 2011

Page 20: From Ruby to Haskell (Kansai Yami RubyKaigi)

side effect to get a val• Ruby

• a = getsp a

•Haskell

• do a <- getContent print a

• getContent >>= print

Sunday, November 13, 2011

Page 21: From Ruby to Haskell (Kansai Yami RubyKaigi)

self-introduction

Sunday, November 13, 2011

Page 22: From Ruby to Haskell (Kansai Yami RubyKaigi)

Tatsuhiro Ujihisa• @ujm

• Vancouver

• HootSuite media inc

• Vim

Sunday, November 13, 2011

Page 23: From Ruby to Haskell (Kansai Yami RubyKaigi)

• http://ujihisa.blogspot.com

• http://vim-users.jp

• http://github.com/ujihisa

Sunday, November 13, 2011

Page 24: From Ruby to Haskell (Kansai Yami RubyKaigi)

Haskell (3/3)

Sunday, November 13, 2011

Page 25: From Ruby to Haskell (Kansai Yami RubyKaigi)

re: FizzBuzz in Haskell 1 def main 2 puts fizzbuzz 3 end 4 5 def fizzbuzz 6 f = -> i do 7 i % 15 == 0 ? 'FizzBuzz' : 8 i % 5 == 0 ? 'Buzz' : 9 i % 3 == 0 ? 'Fizz' :10 i11 end12 (1..100).map &f13 end14 15 main

1 main = print fizzbuzz2 3 fizzbuzz = map f [1..100]4 where f n5 | n `rem` 15 == 0 = "FizzBuzz"6 | n `rem` 5 == 0 = "Buzz"7 | n `rem` 3 == 0 = "Fizz"8 | otherwise = show n

Sunday, November 13, 2011

Page 26: From Ruby to Haskell (Kansai Yami RubyKaigi)

output1 main = print fizzbuzz2 3 fizzbuzz = map f [1..100]4 where f n5 | n `rem` 15 == 0 = "FizzBuzz"6 | n `rem` 5 == 0 = "Buzz"7 | n `rem` 3 == 0 = "Fizz"8 | otherwise = show n

["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz","16","17","Fizz","19","Buzz","Fizz","22","23","Fizz","Buzz","26","Fizz","28","29","FizzBuzz","31","32","Fizz","34","Buzz","Fizz","37","38","Fizz","Buzz","41","Fizz","43","44","FizzBuzz","46","47","Fizz","49","Buzz","Fizz","52","53","Fizz","Buzz","56","Fizz","58","59","FizzBuzz","61","62","Fizz","64","Buzz","Fizz","67","68","Fizz","Buzz","71","Fizz","73","74","FizzBuzz","76","77","Fizz","79","Buzz","Fizz","82","83","Fizz","Buzz","86","Fizz","88","89","FizzBuzz","91","92","Fizz","94","Buzz","Fizz","97","98","Fizz","Buzz

"]

like p

Sunday, November 13, 2011

Page 27: From Ruby to Haskell (Kansai Yami RubyKaigi)

output1 main = mapM_ putStrLn fizzbuzz2 3 fizzbuzz = map f [1..100]4 where f n5 | n `rem` 15 == 0 = "FizzBuzz"6 | n `rem` 5 == 0 = "Buzz"7 | n `rem` 3 == 0 = "Fizz"8 | otherwise = show n

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617Fizz19BuzzFizz2223FizzBuzz26Fizz2829FizzBuzz3132Fizz34BuzzFizz3738FizzBuzz41Fizz4344FizzBuzz4647Fizz49BuzzFizz5253FizzBuzz56Fizz5859FizzBuzz6162Fizz64BuzzFizz6768FizzBuzz71Fizz7374FizzBuzz7677Fizz79BuzzFizz8283FizzBuzz86Fizz8889FizzBuzz9192Fizz94BuzzFizz9798FizzBuzz

like puts

Sunday, November 13, 2011

Page 28: From Ruby to Haskell (Kansai Yami RubyKaigi)

mapM_• f x >> f y >> f z

• do f x f y f z

• mapM_ f [x, y, z]

Sunday, November 13, 2011

Page 29: From Ruby to Haskell (Kansai Yami RubyKaigi)

mapM_• ((f x) >> f y) >> f z

• foldl1 (>>) $ map f [x, y, z]

• f x >> (f y >> (f z))

• foldr1 (>>) $ map f [x, y, z]

• sequence_ (map f [x, y, z])

Sunday, November 13, 2011

Page 30: From Ruby to Haskell (Kansai Yami RubyKaigi)

1 main = mapM_ putStrLn fizzbuzz2 3 fizzbuzz = map f [1..100]4 where f n5 | n `rem` 15 == 0 = "FizzBuzz"6 | n `rem` 5 == 0 = "Buzz"7 | n `rem` 3 == 0 = "Fizz"8 | otherwise = show n

1 main = mapM_ putStrLn fizzbuzz2 3 fizzbuzz = map f [1..100]4 where f n = case () of5 n `rem` 15 == 0 -> "FizzBuzz"6 n `rem` 5 == 0 -> "Buzz"7 n `rem` 3 == 0 -> "Fizz"8 otherwise -> show n

Sunday, November 13, 2011

Page 31: From Ruby to Haskell (Kansai Yami RubyKaigi)

map, flip, and for• map f list

• flip map list f

• mapM_ f list

• flip mapM_ list f

• forM_ list f

Sunday, November 13, 2011

Page 32: From Ruby to Haskell (Kansai Yami RubyKaigi)

1 import Control.Monad (forM_)2 main = forM_ [1..100] f3 where4 f n = putStrLn $ case () of _5 | n `rem` 15 == 0 -> "FizzBuzz"6 | n `rem` 5 == 0 -> "Buzz"7 | n `rem` 3 == 0 -> "Fizz"8 | otherwise -> show n

1 main = mapM_ putStrLn fizzbuzz2 3 fizzbuzz = map f [1..100]4 where f n = case () of _5 | n `rem` 15 == 0 -> "FizzBuzz"6 | n `rem` 5 == 0 -> "Buzz"7 | n `rem` 3 == 0 -> "Fizz"8 | otherwise -> show n

Sunday, November 13, 2011

Page 33: From Ruby to Haskell (Kansai Yami RubyKaigi)

1 import Control.Monad (forM_)2 main = forM_ [1..100] f3 where4 f n = putStrLn $ case () of _5 | n `rem` 15 == 0 -> "FizzBuzz"6 | n `rem` 5 == 0 -> "Buzz"7 | n `rem` 3 == 0 -> "Fizz"8 | otherwise -> show n

1 import Control.Monad (forM_)2 main = forM_ [1..100] $ \n ->3 putStrLn $ case () of _4 | n `rem` 15 == 0 -> "FizzBuzz"5 | n `rem` 5 == 0 -> "Buzz"6 | n `rem` 3 == 0 -> "Fizz"7 | otherwise -> show n

Sunday, November 13, 2011

Page 34: From Ruby to Haskell (Kansai Yami RubyKaigi)

Haskell as shell scripts• Succinct expressions

• Powerful list-manipulation

• Powerful text-manipulation

• Reasonably fast to boot

• Healthy

Sunday, November 13, 2011

Page 35: From Ruby to Haskell (Kansai Yami RubyKaigi)

Parsec• Parser combinators

• Standard library

• No need for handling state explicitly

Sunday, November 13, 2011

Page 36: From Ruby to Haskell (Kansai Yami RubyKaigi)

Haskell web framework• Yesod

• Snap (framework)

Sunday, November 13, 2011

Page 37: From Ruby to Haskell (Kansai Yami RubyKaigi)

Appendix• IDE-integration

• run on the IDE

• keyword completion

• Prelude type/function completion

• module name completion

• third party t/f completion

• pragma completion

Sunday, November 13, 2011

Page 38: From Ruby to Haskell (Kansai Yami RubyKaigi)

quickrun.vim• DEMO

• runghc

• ghc

Sunday, November 13, 2011