Hack Bulgaria
github.com/HackBulgaria
Тъй като може да не ми стигне времето, ще се представя накрая.
Както за решаването на проблема, така и за дизайна на кода.
module Split ( split ) where
split :: Eq a => [a] -> [a] -> [[a]]
split delimiter items = go delimiter items [[]]
where
dl = length delimiter
go _ [] result = result
go xs (y:ys) result@(r:rs)
| xs == (take dl (y:ys)) = go xs (drop dl (y:ys)) ([] : result)
| otherwise = go xs ys ((y:r):rs)
a = a + 1 не съществува
Рекурсията е вашият най-добър приятел.
No Side Effects.
# Python
x = 2;
def inc_x():
global x
x = x + 1
def times_x(n):
global x
return x * n
times_x(5)
inc_x()
times_x(5)
-- a.hs (this is a comment)
f x = x * x
-- b.hs
inInterval :: Int -> Int -> Int -> Bool
inInterval a b x = x >= a && x <= b
-- c.hs
confIt cities = map (\city -> city ++ "Conf") cities
*Main> confIt ["Plovdiv", "Varna", "Tarnovo", "Pleven"]
["PlovdivConf","VarnaConf","TarnovoConf","PlevenConf"]
*Main> :t confIt
confIt :: [[Char]] -> [[Char]]
Компилаторът е по-умен от нас.
String = [Char]
Стандарните неща, които очаквате от един типизиран език.
-- d.hs
first [] = error "Empty list"
first (x:_) = x
-- first [1,2,3] -> 1
-- first ["asd", "wtf"] -> "asd"
-- first [True, False] -> True
Според вас, каква е сигнатурата на first?
a може да е всякакъв тип.
-- d.hs
first :: [a] -> a
first [] = error "Empty list"
first (x:_) = x
Малко по-дълбоко.
member [] = False
member y (x:xs) = y == x || member y xs
*Main> :t member
member :: Eq a => a -> [a] -> Bool
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not (x /= y)
x /= y = not (x == y)
data TrafficLight = Red | Yellow | Green
instance Eq TrafficLight where
Red == Red = True
Green == Green = True
Yellow == Yellow = True
_ == _ = False
Една функция, извикана два пъти с еднакви аргументи, трябва да даде един и същи резултат.
# Python
from random import randint
randint(1, 10) # 5
randint(1, 10) # 6
Счупихме Haskell ;(
-- f.hs
import System.Random
randomRange a b = getStdRandom (randomR (a,b))
-- f.hs
import System.Random
randomRange :: Random a => a -> a -> IO a
randomRange a b = getStdRandom (randomR (a,b))
f :: IO String -> String
Каквото се докосне до IO, става IO
-- g.hs
main :: IO ()
main = putStrLn "Hello World!"
=<<, >>=, <-, ->, <*>, <$>, asd, wtf, etc.
-- h.hs
main :: IO ()
main = getLine >>= putStrLn
-- i.hs
import System.Random
randomRange :: Random a => a -> a -> IO a
randomRange a b = getStdRandom (randomR (a,b))
main :: IO ()
main = do
name <- getLine
putStrLn $ "Hello, " ++ name
randomNumber <- randomRange 1 10 :: (IO Int)
let squareRandom = randomNumber * randomNumber
putStrLn $ "Your lucky number is : " ++ (show randomNumber)
putStrLn $ "And the square is : " ++ (show squareRandom)
* не се подвеждайте от цветното.
By Hack Bulgaria
Migrated slides from reveal.js here