Successfully reported this slideshow.

Haskell Lite - presentation for DevDay about Haskell language

2

Share

YouTube videos are no longer supported on SlideShare

View original on YouTube

Haskell
Александр Гранин
graninas@gmail.com
О чем доклад?
● Часть 1. Ликбез по ФП и Haskell
○ Функциональное программирование
○ Язык Haskell. Применимость языка
○ Язы...
Loading in …3
×
1 of 93
1 of 93

Haskell Lite - presentation for DevDay about Haskell language

2

Share

Description

Presentation about Haskell programming language.
DevDay, 31.05.2013, Novosibirsk
Video: http://www.youtube.com/watch?v=ieOhEX1RCB8

Transcript

  1. 1. Haskell Александр Гранин graninas@gmail.com
  2. 2. О чем доклад? ● Часть 1. Ликбез по ФП и Haskell ○ Функциональное программирование ○ Язык Haskell. Применимость языка ○ Язык Haskell. Основы ○ Инструменты разработчика ● Часть 2. Haskell: We need to go deeper ○ Обработка данных: NgnTrafficParser ○ XML и Domain Specific Languages ○ Parsec, HaXml, GenXml ● Часть 3. Немного хардкора ○ Монады!!!
  3. 3. Программирование: ● Императивное ● Объектно-ориентированное ● Функциональное ● Логическое ● Декларативное
  4. 4. (println "Hello World!") printfn "Hello World!" io:format("Hello, World!~n"). putStrLn "Hello World!" println("Hello World!")
  5. 5. Функциональное программирование ?
  6. 6. Функциональное программирование ● Все есть функция ● ... ● ... ● ... ● ... ● ...
  7. 7. Функциональное программирование ● Все есть функция ● Рекурсия ● ... ● ... ● ... ● ...
  8. 8. Функциональное программирование ● Все есть функция ● Рекурсия ● Функции высших порядков ● ... ● ... ● ...
  9. 9. Функциональное программирование a := 1 a := 2 DO NOT CHANGE! The immutability is with you ● Все есть функция ● Рекурсия ● Функции высших порядков ● Иммутабельность данных ● ... ● ...
  10. 10. Функциональное программирование ● Все есть функция ● Рекурсия ● Функции высших порядков ● Иммутабельность данных ● Чистые функции ● ...
  11. 11. Функциональное программирование ● Все есть функция ● Рекурсия ● Функции высших порядков ● Иммутабельность данных ● Чистые функции ● Нет побочных эффектов
  12. 12. Язык Haskell ?
  13. 13. Язык Haskell Haskell - это... ● Чистый функциональный, ● строго статически типизированный, ● кроссплатформенный, ● компилируемый язык ● общего назначения ● с ленивой семантикой ● и автоматическим выводом типов.
  14. 14. Краткая история Haskell ● В честь Хаскеля Карри ● GHC: Саймон Пейтон Джонс ● Семейство языков ML ● Прародитель - Miranda ● 1990 год - Haskell 1.0 ● 1998 год - Haskell '98 ● 2009 год - Haskell 2010 «Доказательство — это программа, а доказываемая формула — это тип программы» (c)MiranLipovača
  15. 15. Где Haskell плох: ● Системное программирование ● Real-time системы ● GUI
  16. 16. Где Haskell хорош: ● Надежность кода
  17. 17. ● Надежность кода ● Domain Specific Languages Abstract Syntax Tree Code base Где Haskell хорош:
  18. 18. ● Надежность кода ● Domain Specific Languages ● Безопасный параллелизм Где Haskell хорош:
  19. 19. ● Надежность кода ● Domain Specific Languages ● Безопасный параллелизм ● Обработка данных Телекомы: TrafficParser Где Haskell хорош:
  20. 20. ● Надежность кода ● Domain Specific Languages ● Безопасный параллелизм ● Обработка данных ● Парсинг Где Haskell хорош: Name Description Body Type XML DSL
  21. 21. Haskell - не мэйнстрим?..
  22. 22. Причины непопулярности ● Pascal, C, C++, Java, C# - в вузах ● Традиционное мировоззрение очень сильно ● Заработать на Haskell очень трудно ● Мифы и стереотипы "Избегать успеха любой ценой." Саймон Пейтон Джонс
  23. 23. Язык Haskell: Основы
  24. 24. fib n = case n of 0 -> 0 1 -> 1 n -> fib (n-1) + fib (n-2) fact n = case n of 0 -> 1 n -> fact (n-1) * n Функции. case - аналог switch Функции, аргументы - lowerCamelCase
  25. 25. fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) fact 0 = 1 fact n = fact (n-1) * n Сопоставление с образцом Функции, аргументы - lowerCamelCase
  26. 26. fib :: Word -> Word fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) fact :: Word -> Word fact 0 = 1 fact n = fact (n-1) * n Система типов Функции, аргументы - lowerCamelCase Типы, классы типов, модули - UpperCamelCase
  27. 27. fact :: Word -> Word replicate :: Int -> a -> [a] map :: (a -> b) -> [a] -> [b] (+) :: Int -> Int -> Int add :: Int -> Int -> Int Система типов
  28. 28. Списки. Кортежи phonebook :: [(String, String)] phonebook = [ ("Bob", "953 777-44-45") , ("Fred", "919 33-555-11") , ("Alice", "383 11111111") , ("Jane", "964 4000004") ]
  29. 29. Списки. Кортежи type PhoneBook = [(String, String)] validate :: PhoneBook -> PhoneBook validate book= map addPrefix book addPrefix :: (String, String) -> (String, String) addPrefix (name, phone) = (name, "+7 " ++ phone)
  30. 30. Лямбды - анонимные функции nums = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0] oddNumbers = filter (n -> odd n) nums oddNumbers2 = filter odd nums // C#: int[] nums = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var oddNumbers = nums.Where(n => n % 2 == 1);
  31. 31. Генераторы списков (c) Miran Lipovača http://learnyouahaskell.com/
  32. 32. Cоздать список: 1. На множестве от 1 до 100. 2. Только нечетные. 3. Делящиеся на 3 без остатка. 4. Делящиеся на 7 без остатка. list1 = [21, 63] list2 = [x | x <- [1..100], odd x, x `mod` 3 == 0, x `mod` 7 == 0]
  33. 33. 1. x - от 1 до 100, y - от 100 до 200. 2. x - четные, y - нечетные. 3. x + y < 200. 4. |x - y| > 190. Cоздать список [(x, y)]: list = [(x, y) | x <- [1..100], even x, y <- [100..200], odd y, x + y < 200, abs (x - y) > 190]
  34. 34. Алгебраические типы данных data Bool = True | False Тип Конструкторы
  35. 35. Алгебраические типы данных data STree = Tip | Branch { leftBranch :: STree, value :: Int, rightBranch :: STree }
  36. 36. Сопоставление с образцом height :: STree -> Int height Tip = 0 height (Branch lt _ rt) = 1 + max (height lt) (height rt) 5 3 7 1 4
  37. 37. Data.Maybe - аналог Nullable phonebook :: [(String, String)] ... printPhone :: String -> [(String, String)] -> IO () printPhone name book = case lookup name book of Nothing -> putStrLn "Name not exist." Just phone -> putStrLn phone data Maybe a = Nothing | Just a lookup :: Eq a => a -> [(a, b)] -> Maybe b
  38. 38. Инструменты разработки
  39. 39. Haskell Platform ● Компилятор GHC ● Интерпретатор GHCi ● Базовые библиотеки ● Пакетный менеджер Cabal ● Документирование - Haddock ● MinGW (Windows) http://www.haskell.org/platform/
  40. 40. Glasgow Haskell Compiler Компиляция: ghc --make FizzBuzz.hs ghc --make -O2 FizzBuzz.hs ghc --make -O2 -threaded FizzBuzz.hs Выполнение: runghc FizzBuzz.hs
  41. 41. REPL - GHCi (GHC interpreter) Read EvalPrint Loop
  42. 42. REPL - GHCi (GHC interpreter) > [1..10] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > (3 + 30) 33 > fizzBuzz <interactive>:1:1: No instance for (Show (Int -> String)) arising from a use of 'print' Possible fix: add an instance declaration for (Show (Int -> String)) In a stmt of an interactive GHCi command: print it
  43. 43. Hackage - репозиторий библиотек
  44. 44. Библиотеки и программы ● xmonad - тайловый оконный менеджер ● Parsec - комбинаторные парсеры ● HaXmL, HXT - обработка XML ● darcs - система контроля версий ● Yesod - RESTful веб-фреймворк ● QuickCheck - тестирование кода ● House, Kinetic - операционные системы ● Всевозможные эффективные коллекции ● OpenGL, OpenAL, OpenCL биндинги ● ... несколько игр и многое другое
  45. 45. IDE
  46. 46. EclipseFP
  47. 47. Leksah
  48. 48. SublimeHaskell
  49. 49. Want more?
  50. 50. NGN Traffic Parser |R200|99999|333333|CR,CS,AM|1|1|3022|222222|333333|||... |R200|44455|012345|CR,CS,AM|1|1|3022|555555|111111|||... |R200|45678|543210|CR,CS,AM|1|1|3022|444444|555555|||... |R200|88888|222222|CR,CS,AM|1|1|3022|666666|777777|||... file1.txt file2.txt ......... Billing CMD, DTS, SQL
  51. 51. NGN Traffic Parser Billing Merge Files Process data MS SQL DTS
  52. 52. АТД: Predicate data Predicate = NotInList [ByteString] | InList [ByteString] | Like [ByteString] | LengthLess Int type PredicateMap = [(FieldIndex, Predicate)] predicates = [ (7, NotInList (map C.pack ["3022", "3012"])) , (8, Like [C.pack "44", C.pack "45"]) , (9, LengthLess 7) ]
  53. 53. NGN Traffic Parser checkPredicate :: Predicate -> C.ByteString -> Bool checkPredicate (NotInList l) str = (not . elem str) l checkPredicate (InList l) str = elem str l checkPredicate (LengthLess n) str = (length str) < n Алгебраический тип данных, Сопоставление с образцом replaceSymbols :: String -> String replaceSymbols s = map (replaceChar '|' ' ') ((map (replaceChar ' ' '*') (refieldDoubles s))) Ver. 2.0 ByteString Ver. 1.0 String
  54. 54. XML и Domain Specific Languages
  55. 55. <?xml version="1.0" encoding="utf-8" ?> - <PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd- PolicySetId="PolicSet-04b0613533354df196715b032388325c" Vers PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combin permit-overrides"> <Description>All active policices</Description> <Target /> - <Policy PolicyId="a25099f1-d6fd-412e-b827-65fd39f799e1" Versio <Description>Match file(s) content</Description> <Target /> Политики безопасности XML
  56. 56. Тестирование политики Алгоритмы тестирования: Безопасность обеспечена? Нет Исправляем дыры Да ОК, запускаем!! Policy.xml
  57. 57. Policy.xml XML?!. Сложно! Хочу DSL! Алгоритмы тестирования: Безопасность обеспечена? Нет Исправляем дыры Да ОК, запускаем!! MyPolicy.dsl
  58. 58. Пример DSL efm := ExactFileMatching 2 ".test2.db" 0 cat2 : "CAT2" = Category [] NoMatch cat1 := Category [cat2] NoMatch cat3 := Category [] NoMatch cat0 := TopCategory [cat1, cat3] NoMatch rule := Rule Permit [] | n_of 1 (Evaluate [efm]) [cat0] policy := Policy DenyOverrides [Audit Deny Medium] [rule] policySet := PolicySet PermitOverrides [] [policy]
  59. 59. Архитектура DSL <-> XML Policy.xml Policy.dsl Policy AST HaXmlGenXml Custom writerParsec DSL AST Translator
  60. 60. DSL: AST на ADT data DslTokenName = DslTokenName String data DslTokenBody = DslGuardedBody { dtbDslAdt :: DslAdt , dtbDslExpression :: DslExpression } | DslNonGuardedBody { dtbDslAdt :: DslAdt } data DslToken = EmptyDslToken | DslToken { dtDslTokenType :: DslTokenType , dtDslTokenName :: DslTokenName , dtDslTokenDescr :: DslTokenDescription , dtDslTokenBody :: DslTokenBody }
  61. 61. Parsec: парсинг DSL dslToken :: GenParser Char st DslToken dslToken = do tName <- dslTokenName tDescr <- dslTokenDescription (tBody, tType) <- dslTokenBody return (DslToken tType tName tDescr tBody) dslTokenBody :: GenParser Char st (DslTokenBody, DslTokenType) dslTokenBody = spaces >> ( try dslGuardedTokenBody <|> try dslNonGuardedTokenBody <?> "dslTokenBody") NonGuardedBody GuardedBody Name Description Body Type DslToken DslTokenBody
  62. 62. Связь с БНФ lower ::= 'a' | 'b' | ... | 'z' rest ::= (letters | numbers | '_') + rest | '' identifier ::= (lower | '_') + rest tokenName ::= identifier tokenBody ::= guardedBody | nonGuardedBody token ::= (tokenType, tokenName, tokenDescr, tokenBody) identifier :: GenParser Char st String identifier = do c <- (lower <|> char '_') rest <- many (alphaNum <|> char '_') return (c : rest)
  63. 63. HaXml: парсинг XML toCondition :: Content i -> Maybe Condition toCondition e = let exprCond = head . filterNonTextContent $ children e expr = fromJust $ recognizeStructure expRecognizers exprCond in Just (Condition expr) -- ............ Здесь много кода parsePolicy :: String -> PolicySet parsePolicy content = let (Document _ _ root _) = xmlParse "error.log" content in toPolicySet (CElem root noPos)
  64. 64. GenXml: генерация XML writeDteValue :: DataTypeExt -> Xml Elem writeDteValue (DteString s) = xtext s writeDteValue (DteBoolean b) = xtext (map toLower (show b)) writeDteValue (DteInteger i) = xtext (show i) writeAttributeValue :: AttributeValue -> Xml Elem writeAttributeValue (AttributeValue dataType val) = let attrValAttributes = xattr dataTypeN dataType attrValVals = writeDteValue val in xelem attributeValueN (attrValAttributes <#> attrValVals)
  65. 65. А теперь - хардкор!!!
  66. 66. lookup :: Eq a => a -> [(a, b)] -> Maybe b class Eq a where (==), (/=) :: a -> a -> Bool instance Eq Char where c1 == c2 = ... -- compare chars c1 /= c2 = not (c1 == c2) instance Eq Int where i1 == i2 = ... -- compare ints i1 /= i2 = not (i1 == i2) Классы типов - "интерфейсы" на стероидах
  67. 67. data Predicate = NotInList [ByteString] | InList [ByteString] | Like [ByteString] | LengthLess Int deriving (Eq, Show, Read) Классы типов - "интерфейсы" на стероидах
  68. 68. Монада IO: Безопасный ввод-выод
  69. 69. let rndGen1 = mkStdGen 100 let (val1, rndGen2) = random rndGen1 let (val2, rndGen3) = random rndGen2 Отправной пример: Random generator
  70. 70. Стратегия связывания, IO getName :: IO () getName = do putStrLn "What is your name?" yourName <- getLine putStr "Hello, " putStrLn (yourName ++ "!") let world0 = getWorld let (val1, world1) = ioAction1 world0 let (val2, world2) = ioAction2 world1
  71. 71. do-нотация getName :: IO () getName = do putStrLn "What is your name?" yourName <- getLine putStr "Hello, " putStrLn (yourName ++ "!") getName' = putStrLn "What is your name?" >> getLine >>= yourName -> putStr "Hello, " >> putStrLn (yourName ++ "!")
  72. 72. Возвращаемое значение getName :: IO String getName = do putStrLn "What is your name?" yourName <- getLine putStr "Hello, " putStrLn (yourName ++ "!") return yourName return :: a -> m a a :: String m :: IO
  73. 73. Монада State newtype State s a = State { runState :: s -> (a, s) }
  74. 74. Монада State myFunc :: State Int Int myFunc = do val <- get put (val - 8) get getNumber = evalState myFunc 50 main = print getNumber
  75. 75. Стратегия связывания, State let state1 = evalState 50 let (val1, state2) = get state1 let ((), state3) = put (val1 - 8) state2 let (val2, state4) = get state3
  76. 76. Monad transformers? Зачем это надо? Монада 2Монада 1
  77. 77. Monad transformers? Зачем это надо? Монада 2 Монада 1
  78. 78. State + IO data GS = GS { worldMap :: [Location] , currentLocation :: Location , welded :: Bool , bucketFull :: Bool } deriving (Show) newtype GameState a = GameState { runGameState :: StateT GS IO a }
  79. 79. State + IO run :: GameState Result run = do t <- get -- read a command from the user io . putStr $ "> " io . hFlush $ stdout line <- io getLine result <- case parseCommand line of Nothing -> write "Invalid command!" >> continue Just cmd -> do ...........
  80. 80. Named + IO -- Int-named IO calculations: intNamedFunc :: NamedT Int IO Int intNamedFunc = do name <- getName return name testIntNamed :: IO () testIntNamed = do name <- evalNamedT intNamedFunc 1 print name -- You got output: 1
  81. 81. Спасибо за внимание! Haskell Александр Гранин graninas@gmail.com
  82. 82. Haskell Scala Clojure ... Want more? PLUG IN!!!
  83. 83. FUNction It's all Haskell is about
  84. 84. Lambda The Gathering
  85. 85. Lambda Lifter
  86. 86. http://bit.ly/17CyYFj Haskell Links
  87. 87. http://hackage.haskell.org/packages/hackage.html Hackage - репозиторий библиотек
  88. 88. Haskell Platform ● Компилятор GHC ● Интерпретатор GHCi ● Базовые библиотеки ● Пакетный менеджер Cabal ● Документирование - Haddock ● MinGW (Windows) http://www.haskell.org/platform/
  89. 89. http://habrahabr. ru/company/selectel/blog/13585 8/ Success Stories
  90. 90. Success Stories Want more? http://www.haskell.org/haskellwiki/Haskell_in_industry
  91. 91. Класс типов Monad class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a
  92. 92. Монада Named - именованные вычисления data Named n a = Named { runNamed :: (n -> a) } instance Monad (Named n) where return x = Named (_ -> x) x >>= f = Named (name -> let a = runNamed x name in runNamed (f a) name)

Description

Presentation about Haskell programming language.
DevDay, 31.05.2013, Novosibirsk
Video: http://www.youtube.com/watch?v=ieOhEX1RCB8

Transcript

  1. 1. Haskell Александр Гранин graninas@gmail.com
  2. 2. О чем доклад? ● Часть 1. Ликбез по ФП и Haskell ○ Функциональное программирование ○ Язык Haskell. Применимость языка ○ Язык Haskell. Основы ○ Инструменты разработчика ● Часть 2. Haskell: We need to go deeper ○ Обработка данных: NgnTrafficParser ○ XML и Domain Specific Languages ○ Parsec, HaXml, GenXml ● Часть 3. Немного хардкора ○ Монады!!!
  3. 3. Программирование: ● Императивное ● Объектно-ориентированное ● Функциональное ● Логическое ● Декларативное
  4. 4. (println "Hello World!") printfn "Hello World!" io:format("Hello, World!~n"). putStrLn "Hello World!" println("Hello World!")
  5. 5. Функциональное программирование ?
  6. 6. Функциональное программирование ● Все есть функция ● ... ● ... ● ... ● ... ● ...
  7. 7. Функциональное программирование ● Все есть функция ● Рекурсия ● ... ● ... ● ... ● ...
  8. 8. Функциональное программирование ● Все есть функция ● Рекурсия ● Функции высших порядков ● ... ● ... ● ...
  9. 9. Функциональное программирование a := 1 a := 2 DO NOT CHANGE! The immutability is with you ● Все есть функция ● Рекурсия ● Функции высших порядков ● Иммутабельность данных ● ... ● ...
  10. 10. Функциональное программирование ● Все есть функция ● Рекурсия ● Функции высших порядков ● Иммутабельность данных ● Чистые функции ● ...
  11. 11. Функциональное программирование ● Все есть функция ● Рекурсия ● Функции высших порядков ● Иммутабельность данных ● Чистые функции ● Нет побочных эффектов
  12. 12. Язык Haskell ?
  13. 13. Язык Haskell Haskell - это... ● Чистый функциональный, ● строго статически типизированный, ● кроссплатформенный, ● компилируемый язык ● общего назначения ● с ленивой семантикой ● и автоматическим выводом типов.
  14. 14. Краткая история Haskell ● В честь Хаскеля Карри ● GHC: Саймон Пейтон Джонс ● Семейство языков ML ● Прародитель - Miranda ● 1990 год - Haskell 1.0 ● 1998 год - Haskell '98 ● 2009 год - Haskell 2010 «Доказательство — это программа, а доказываемая формула — это тип программы» (c)MiranLipovača
  15. 15. Где Haskell плох: ● Системное программирование ● Real-time системы ● GUI
  16. 16. Где Haskell хорош: ● Надежность кода
  17. 17. ● Надежность кода ● Domain Specific Languages Abstract Syntax Tree Code base Где Haskell хорош:
  18. 18. ● Надежность кода ● Domain Specific Languages ● Безопасный параллелизм Где Haskell хорош:
  19. 19. ● Надежность кода ● Domain Specific Languages ● Безопасный параллелизм ● Обработка данных Телекомы: TrafficParser Где Haskell хорош:
  20. 20. ● Надежность кода ● Domain Specific Languages ● Безопасный параллелизм ● Обработка данных ● Парсинг Где Haskell хорош: Name Description Body Type XML DSL
  21. 21. Haskell - не мэйнстрим?..
  22. 22. Причины непопулярности ● Pascal, C, C++, Java, C# - в вузах ● Традиционное мировоззрение очень сильно ● Заработать на Haskell очень трудно ● Мифы и стереотипы "Избегать успеха любой ценой." Саймон Пейтон Джонс
  23. 23. Язык Haskell: Основы
  24. 24. fib n = case n of 0 -> 0 1 -> 1 n -> fib (n-1) + fib (n-2) fact n = case n of 0 -> 1 n -> fact (n-1) * n Функции. case - аналог switch Функции, аргументы - lowerCamelCase
  25. 25. fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) fact 0 = 1 fact n = fact (n-1) * n Сопоставление с образцом Функции, аргументы - lowerCamelCase
  26. 26. fib :: Word -> Word fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) fact :: Word -> Word fact 0 = 1 fact n = fact (n-1) * n Система типов Функции, аргументы - lowerCamelCase Типы, классы типов, модули - UpperCamelCase
  27. 27. fact :: Word -> Word replicate :: Int -> a -> [a] map :: (a -> b) -> [a] -> [b] (+) :: Int -> Int -> Int add :: Int -> Int -> Int Система типов
  28. 28. Списки. Кортежи phonebook :: [(String, String)] phonebook = [ ("Bob", "953 777-44-45") , ("Fred", "919 33-555-11") , ("Alice", "383 11111111") , ("Jane", "964 4000004") ]
  29. 29. Списки. Кортежи type PhoneBook = [(String, String)] validate :: PhoneBook -> PhoneBook validate book= map addPrefix book addPrefix :: (String, String) -> (String, String) addPrefix (name, phone) = (name, "+7 " ++ phone)
  30. 30. Лямбды - анонимные функции nums = [5, 4, 1, 3, 9, 8, 6, 7, 2, 0] oddNumbers = filter (n -> odd n) nums oddNumbers2 = filter odd nums // C#: int[] nums = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var oddNumbers = nums.Where(n => n % 2 == 1);
  31. 31. Генераторы списков (c) Miran Lipovača http://learnyouahaskell.com/
  32. 32. Cоздать список: 1. На множестве от 1 до 100. 2. Только нечетные. 3. Делящиеся на 3 без остатка. 4. Делящиеся на 7 без остатка. list1 = [21, 63] list2 = [x | x <- [1..100], odd x, x `mod` 3 == 0, x `mod` 7 == 0]
  33. 33. 1. x - от 1 до 100, y - от 100 до 200. 2. x - четные, y - нечетные. 3. x + y < 200. 4. |x - y| > 190. Cоздать список [(x, y)]: list = [(x, y) | x <- [1..100], even x, y <- [100..200], odd y, x + y < 200, abs (x - y) > 190]
  34. 34. Алгебраические типы данных data Bool = True | False Тип Конструкторы
  35. 35. Алгебраические типы данных data STree = Tip | Branch { leftBranch :: STree, value :: Int, rightBranch :: STree }
  36. 36. Сопоставление с образцом height :: STree -> Int height Tip = 0 height (Branch lt _ rt) = 1 + max (height lt) (height rt) 5 3 7 1 4
  37. 37. Data.Maybe - аналог Nullable phonebook :: [(String, String)] ... printPhone :: String -> [(String, String)] -> IO () printPhone name book = case lookup name book of Nothing -> putStrLn "Name not exist." Just phone -> putStrLn phone data Maybe a = Nothing | Just a lookup :: Eq a => a -> [(a, b)] -> Maybe b
  38. 38. Инструменты разработки
  39. 39. Haskell Platform ● Компилятор GHC ● Интерпретатор GHCi ● Базовые библиотеки ● Пакетный менеджер Cabal ● Документирование - Haddock ● MinGW (Windows) http://www.haskell.org/platform/
  40. 40. Glasgow Haskell Compiler Компиляция: ghc --make FizzBuzz.hs ghc --make -O2 FizzBuzz.hs ghc --make -O2 -threaded FizzBuzz.hs Выполнение: runghc FizzBuzz.hs
  41. 41. REPL - GHCi (GHC interpreter) Read EvalPrint Loop
  42. 42. REPL - GHCi (GHC interpreter) > [1..10] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] > (3 + 30) 33 > fizzBuzz <interactive>:1:1: No instance for (Show (Int -> String)) arising from a use of 'print' Possible fix: add an instance declaration for (Show (Int -> String)) In a stmt of an interactive GHCi command: print it
  43. 43. Hackage - репозиторий библиотек
  44. 44. Библиотеки и программы ● xmonad - тайловый оконный менеджер ● Parsec - комбинаторные парсеры ● HaXmL, HXT - обработка XML ● darcs - система контроля версий ● Yesod - RESTful веб-фреймворк ● QuickCheck - тестирование кода ● House, Kinetic - операционные системы ● Всевозможные эффективные коллекции ● OpenGL, OpenAL, OpenCL биндинги ● ... несколько игр и многое другое
  45. 45. IDE
  46. 46. EclipseFP
  47. 47. Leksah
  48. 48. SublimeHaskell
  49. 49. Want more?
  50. 50. NGN Traffic Parser |R200|99999|333333|CR,CS,AM|1|1|3022|222222|333333|||... |R200|44455|012345|CR,CS,AM|1|1|3022|555555|111111|||... |R200|45678|543210|CR,CS,AM|1|1|3022|444444|555555|||... |R200|88888|222222|CR,CS,AM|1|1|3022|666666|777777|||... file1.txt file2.txt ......... Billing CMD, DTS, SQL
  51. 51. NGN Traffic Parser Billing Merge Files Process data MS SQL DTS
  52. 52. АТД: Predicate data Predicate = NotInList [ByteString] | InList [ByteString] | Like [ByteString] | LengthLess Int type PredicateMap = [(FieldIndex, Predicate)] predicates = [ (7, NotInList (map C.pack ["3022", "3012"])) , (8, Like [C.pack "44", C.pack "45"]) , (9, LengthLess 7) ]
  53. 53. NGN Traffic Parser checkPredicate :: Predicate -> C.ByteString -> Bool checkPredicate (NotInList l) str = (not . elem str) l checkPredicate (InList l) str = elem str l checkPredicate (LengthLess n) str = (length str) < n Алгебраический тип данных, Сопоставление с образцом replaceSymbols :: String -> String replaceSymbols s = map (replaceChar '|' ' ') ((map (replaceChar ' ' '*') (refieldDoubles s))) Ver. 2.0 ByteString Ver. 1.0 String
  54. 54. XML и Domain Specific Languages
  55. 55. <?xml version="1.0" encoding="utf-8" ?> - <PolicySet xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd- PolicySetId="PolicSet-04b0613533354df196715b032388325c" Vers PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combin permit-overrides"> <Description>All active policices</Description> <Target /> - <Policy PolicyId="a25099f1-d6fd-412e-b827-65fd39f799e1" Versio <Description>Match file(s) content</Description> <Target /> Политики безопасности XML
  56. 56. Тестирование политики Алгоритмы тестирования: Безопасность обеспечена? Нет Исправляем дыры Да ОК, запускаем!! Policy.xml
  57. 57. Policy.xml XML?!. Сложно! Хочу DSL! Алгоритмы тестирования: Безопасность обеспечена? Нет Исправляем дыры Да ОК, запускаем!! MyPolicy.dsl
  58. 58. Пример DSL efm := ExactFileMatching 2 ".test2.db" 0 cat2 : "CAT2" = Category [] NoMatch cat1 := Category [cat2] NoMatch cat3 := Category [] NoMatch cat0 := TopCategory [cat1, cat3] NoMatch rule := Rule Permit [] | n_of 1 (Evaluate [efm]) [cat0] policy := Policy DenyOverrides [Audit Deny Medium] [rule] policySet := PolicySet PermitOverrides [] [policy]
  59. 59. Архитектура DSL <-> XML Policy.xml Policy.dsl Policy AST HaXmlGenXml Custom writerParsec DSL AST Translator
  60. 60. DSL: AST на ADT data DslTokenName = DslTokenName String data DslTokenBody = DslGuardedBody { dtbDslAdt :: DslAdt , dtbDslExpression :: DslExpression } | DslNonGuardedBody { dtbDslAdt :: DslAdt } data DslToken = EmptyDslToken | DslToken { dtDslTokenType :: DslTokenType , dtDslTokenName :: DslTokenName , dtDslTokenDescr :: DslTokenDescription , dtDslTokenBody :: DslTokenBody }
  61. 61. Parsec: парсинг DSL dslToken :: GenParser Char st DslToken dslToken = do tName <- dslTokenName tDescr <- dslTokenDescription (tBody, tType) <- dslTokenBody return (DslToken tType tName tDescr tBody) dslTokenBody :: GenParser Char st (DslTokenBody, DslTokenType) dslTokenBody = spaces >> ( try dslGuardedTokenBody <|> try dslNonGuardedTokenBody <?> "dslTokenBody") NonGuardedBody GuardedBody Name Description Body Type DslToken DslTokenBody
  62. 62. Связь с БНФ lower ::= 'a' | 'b' | ... | 'z' rest ::= (letters | numbers | '_') + rest | '' identifier ::= (lower | '_') + rest tokenName ::= identifier tokenBody ::= guardedBody | nonGuardedBody token ::= (tokenType, tokenName, tokenDescr, tokenBody) identifier :: GenParser Char st String identifier = do c <- (lower <|> char '_') rest <- many (alphaNum <|> char '_') return (c : rest)
  63. 63. HaXml: парсинг XML toCondition :: Content i -> Maybe Condition toCondition e = let exprCond = head . filterNonTextContent $ children e expr = fromJust $ recognizeStructure expRecognizers exprCond in Just (Condition expr) -- ............ Здесь много кода parsePolicy :: String -> PolicySet parsePolicy content = let (Document _ _ root _) = xmlParse "error.log" content in toPolicySet (CElem root noPos)
  64. 64. GenXml: генерация XML writeDteValue :: DataTypeExt -> Xml Elem writeDteValue (DteString s) = xtext s writeDteValue (DteBoolean b) = xtext (map toLower (show b)) writeDteValue (DteInteger i) = xtext (show i) writeAttributeValue :: AttributeValue -> Xml Elem writeAttributeValue (AttributeValue dataType val) = let attrValAttributes = xattr dataTypeN dataType attrValVals = writeDteValue val in xelem attributeValueN (attrValAttributes <#> attrValVals)
  65. 65. А теперь - хардкор!!!
  66. 66. lookup :: Eq a => a -> [(a, b)] -> Maybe b class Eq a where (==), (/=) :: a -> a -> Bool instance Eq Char where c1 == c2 = ... -- compare chars c1 /= c2 = not (c1 == c2) instance Eq Int where i1 == i2 = ... -- compare ints i1 /= i2 = not (i1 == i2) Классы типов - "интерфейсы" на стероидах
  67. 67. data Predicate = NotInList [ByteString] | InList [ByteString] | Like [ByteString] | LengthLess Int deriving (Eq, Show, Read) Классы типов - "интерфейсы" на стероидах
  68. 68. Монада IO: Безопасный ввод-выод
  69. 69. let rndGen1 = mkStdGen 100 let (val1, rndGen2) = random rndGen1 let (val2, rndGen3) = random rndGen2 Отправной пример: Random generator
  70. 70. Стратегия связывания, IO getName :: IO () getName = do putStrLn "What is your name?" yourName <- getLine putStr "Hello, " putStrLn (yourName ++ "!") let world0 = getWorld let (val1, world1) = ioAction1 world0 let (val2, world2) = ioAction2 world1
  71. 71. do-нотация getName :: IO () getName = do putStrLn "What is your name?" yourName <- getLine putStr "Hello, " putStrLn (yourName ++ "!") getName' = putStrLn "What is your name?" >> getLine >>= yourName -> putStr "Hello, " >> putStrLn (yourName ++ "!")
  72. 72. Возвращаемое значение getName :: IO String getName = do putStrLn "What is your name?" yourName <- getLine putStr "Hello, " putStrLn (yourName ++ "!") return yourName return :: a -> m a a :: String m :: IO
  73. 73. Монада State newtype State s a = State { runState :: s -> (a, s) }
  74. 74. Монада State myFunc :: State Int Int myFunc = do val <- get put (val - 8) get getNumber = evalState myFunc 50 main = print getNumber
  75. 75. Стратегия связывания, State let state1 = evalState 50 let (val1, state2) = get state1 let ((), state3) = put (val1 - 8) state2 let (val2, state4) = get state3
  76. 76. Monad transformers? Зачем это надо? Монада 2Монада 1
  77. 77. Monad transformers? Зачем это надо? Монада 2 Монада 1
  78. 78. State + IO data GS = GS { worldMap :: [Location] , currentLocation :: Location , welded :: Bool , bucketFull :: Bool } deriving (Show) newtype GameState a = GameState { runGameState :: StateT GS IO a }
  79. 79. State + IO run :: GameState Result run = do t <- get -- read a command from the user io . putStr $ "> " io . hFlush $ stdout line <- io getLine result <- case parseCommand line of Nothing -> write "Invalid command!" >> continue Just cmd -> do ...........
  80. 80. Named + IO -- Int-named IO calculations: intNamedFunc :: NamedT Int IO Int intNamedFunc = do name <- getName return name testIntNamed :: IO () testIntNamed = do name <- evalNamedT intNamedFunc 1 print name -- You got output: 1
  81. 81. Спасибо за внимание! Haskell Александр Гранин graninas@gmail.com
  82. 82. Haskell Scala Clojure ... Want more? PLUG IN!!!
  83. 83. FUNction It's all Haskell is about
  84. 84. Lambda The Gathering
  85. 85. Lambda Lifter
  86. 86. http://bit.ly/17CyYFj Haskell Links
  87. 87. http://hackage.haskell.org/packages/hackage.html Hackage - репозиторий библиотек
  88. 88. Haskell Platform ● Компилятор GHC ● Интерпретатор GHCi ● Базовые библиотеки ● Пакетный менеджер Cabal ● Документирование - Haddock ● MinGW (Windows) http://www.haskell.org/platform/
  89. 89. http://habrahabr. ru/company/selectel/blog/13585 8/ Success Stories
  90. 90. Success Stories Want more? http://www.haskell.org/haskellwiki/Haskell_in_industry
  91. 91. Класс типов Monad class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a
  92. 92. Монада Named - именованные вычисления data Named n a = Named { runNamed :: (n -> a) } instance Monad (Named n) where return x = Named (_ -> x) x >>= f = Named (name -> let a = runNamed x name in runNamed (f a) name)

More Related Content

Slideshows for you

More from Alexander Granin

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

×