Haskell Lite - presentation for DevDay about Haskell language

638 views
552 views

Published on

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

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
638
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Haskell Lite - presentation for DevDay about Haskell language

  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 := 1a := 2DO NOT CHANGE!The immutability is with you● Все есть функция● Рекурсия● Функции высшихпорядков● Иммутабельностьданных● ...● ...
  10. 10. Функциональноепрограммирование● Все есть функция● Рекурсия● Функции высшихпорядков● Иммутабельностьданных● Чистые функции● ...
  11. 11. Функциональноепрограммирование● Все есть функция● Рекурсия● Функции высшихпорядков● Иммутабельностьданных● Чистые функции● Нет побочныхэффектов
  12. 12. Язык Haskell?
  13. 13. Язык HaskellHaskell - это...● Чистый функциональный,● строго статически типизированный,● кроссплатформенный,● компилируемый язык● общего назначения● с ленивой семантикой● и автоматическим выводом типов.
  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 LanguagesAbstract SyntaxTreeCode baseГде Haskell хорош:
  18. 18. ● Надежность кода● Domain Specific Languages● Безопасный параллелизмГде Haskell хорош:
  19. 19. ● Надежность кода● Domain Specific Languages● Безопасный параллелизм● Обработка данныхТелекомы:TrafficParserГде Haskell хорош:
  20. 20. ● Надежность кода● Domain Specific Languages● Безопасный параллелизм● Обработка данных● ПарсингГде Haskell хорош:NameDescriptionBody TypeXMLDSL
  21. 21. Haskell - не мэйнстрим?..
  22. 22. Причины непопулярности● Pascal, C, C++, Java, C# - в вузах● Традиционное мировоззрение очень сильно● Заработать на Haskell очень трудно● Мифы и стереотипы"Избегать успеха любой ценой."Саймон Пейтон Джонс
  23. 23. Язык Haskell: Основы
  24. 24. fib n = case n of0 -> 01 -> 1n -> fib (n-1) + fib (n-2)fact n = case n of0 -> 1n -> fact (n-1) * nФункции.case - аналог switchФункции,аргументы -lowerCamelCase
  25. 25. fib 0 = 0fib 1 = 1fib n = fib (n-1) + fib (n-2)fact 0 = 1fact n = fact (n-1) * nСопоставление с образцомФункции,аргументы -lowerCamelCase
  26. 26. fib :: Word -> Wordfib 0 = 0fib 1 = 1fib n = fib (n-1) + fib (n-2)fact :: Word -> Wordfact 0 = 1fact n = fact (n-1) * nСистема типовФункции,аргументы -lowerCamelCaseТипы, классытипов, модули -UpperCamelCase
  27. 27. fact :: Word -> Wordreplicate :: Int -> a -> [a]map :: (a -> b) -> [a] -> [b](+) :: Int -> Int -> Intadd :: 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 -> PhoneBookvalidate book= map addPrefix bookaddPrefix :: (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) numsoddNumbers2 = 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 -> Intheight Tip = 0height (Branch lt _ rt) = 1 + max (height lt) (height rt)53 71 4
  37. 37. Data.Maybe - аналог Nullablephonebook :: [(String, String)]...printPhone :: String -> [(String, String)] -> IO ()printPhone name book = case lookup name book ofNothing -> putStrLn "Name not exist."Just phone -> putStrLn phonedata Maybe a = Nothing| Just alookup :: 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.hsghc --make -O2 FizzBuzz.hsghc --make -O2 -threaded FizzBuzz.hsВыполнение:runghc FizzBuzz.hs
  41. 41. REPL - GHCi(GHC interpreter)ReadEvalPrintLoop
  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 printPossible 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. Wantmore?
  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 .........BillingCMD,DTS,SQL
  51. 51. NGN Traffic ParserBillingMerge FilesProcess dataMS SQL DTS
  52. 52. АТД: Predicatedata Predicate = NotInList [ByteString]| InList [ByteString]| Like [ByteString]| LengthLess Inttype 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 ParsercheckPredicate :: Predicate -> C.ByteString -> BoolcheckPredicate (NotInList l) str = (not . elem str) lcheckPredicate (InList l) str = elem str lcheckPredicate (LengthLess n) str = (length str) < nАлгебраический тип данных,Сопоставление с образцомreplaceSymbols :: String -> StringreplaceSymbols s = map (replaceChar | )((map (replaceChar *)(refieldDoubles s)))Ver. 2.0ByteStringVer. 1.0String
  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" VersPolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combinpermit-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.xmlXML?!. Сложно! Хочу DSL!Алгоритмы тестирования:Безопасность обеспечена?НетИсправляемдырыДаОК, запускаем!!MyPolicy.dsl
  58. 58. Пример DSLefm := ExactFileMatching 2 ".test2.db" 0cat2 : "CAT2" = Category [] NoMatchcat1 := Category [cat2] NoMatchcat3 := Category [] NoMatchcat0 := TopCategory [cat1, cat3] NoMatchrule := Rule Permit [] | n_of 1 (Evaluate [efm]) [cat0]policy := Policy DenyOverrides [Audit Deny Medium] [rule]policySet := PolicySet PermitOverrides [] [policy]
  59. 59. Архитектура DSL <-> XMLPolicy.xmlPolicy.dslPolicy ASTHaXmlGenXmlCustom writerParsecDSL ASTTranslator
  60. 60. DSL: AST на ADTdata DslTokenName = DslTokenName Stringdata DslTokenBody = DslGuardedBody{ dtbDslAdt :: DslAdt, dtbDslExpression :: DslExpression }| DslNonGuardedBody { dtbDslAdt :: DslAdt }data DslToken = EmptyDslToken| DslToken{ dtDslTokenType :: DslTokenType, dtDslTokenName :: DslTokenName, dtDslTokenDescr :: DslTokenDescription, dtDslTokenBody :: DslTokenBody }
  61. 61. Parsec: парсинг DSLdslToken :: GenParser Char st DslTokendslToken = dotName <- dslTokenNametDescr <- dslTokenDescription(tBody, tType) <- dslTokenBodyreturn (DslToken tType tName tDescr tBody)dslTokenBody :: GenParser Char st(DslTokenBody, DslTokenType)dslTokenBody = spaces >> (try dslGuardedTokenBody<|> try dslNonGuardedTokenBody<?> "dslTokenBody")NonGuardedBodyGuardedBodyNameDescriptionBody TypeDslTokenDslTokenBody
  62. 62. Связь с БНФlower ::= a | b | ... | zrest ::= (letters | numbers | _) + rest | identifier ::= (lower | _) + resttokenName ::= identifiertokenBody ::= guardedBody | nonGuardedBodytoken ::= (tokenType, tokenName, tokenDescr, tokenBody)identifier :: GenParser Char st Stringidentifier = doc <- (lower <|> char _)rest <- many (alphaNum <|> char _)return (c : rest)
  63. 63. HaXml: парсинг XMLtoCondition :: Content i -> Maybe ConditiontoCondition e = letexprCond = head . filterNonTextContent $ children eexpr = fromJust $ recognizeStructure expRecognizersexprCondin Just (Condition expr)-- ............ Здесь много кодаparsePolicy :: String -> PolicySetparsePolicy content = let(Document _ _ root _) = xmlParse "error.log" contentin toPolicySet (CElem root noPos)
  64. 64. GenXml: генерация XMLwriteDteValue :: DataTypeExt -> Xml ElemwriteDteValue (DteString s) = xtext swriteDteValue (DteBoolean b) = xtext (map toLower (show b))writeDteValue (DteInteger i) = xtext (show i)writeAttributeValue :: AttributeValue -> Xml ElemwriteAttributeValue (AttributeValue dataType val) = letattrValAttributes = xattr dataTypeN dataTypeattrValVals = writeDteValue valin xelem attributeValueN (attrValAttributes <#> attrValVals)
  65. 65. А теперь - хардкор!!!
  66. 66. lookup :: Eq a => a -> [(a, b)] -> Maybe bclass Eq a where(==), (/=) :: a -> a -> Boolinstance Eq Char wherec1 == c2 = ... -- compare charsc1 /= c2 = not (c1 == c2)instance Eq Int wherei1 == i2 = ... -- compare intsi1 /= i2 = not (i1 == i2)Классы типов -"интерфейсы" на стероидах
  67. 67. data Predicate = NotInList [ByteString]| InList [ByteString]| Like [ByteString]| LengthLess Intderiving (Eq, Show, Read)Классы типов -"интерфейсы" на стероидах
  68. 68. Монада IO:Безопасный ввод-выод
  69. 69. let rndGen1 = mkStdGen 100let (val1, rndGen2) = random rndGen1let (val2, rndGen3) = random rndGen2Отправной пример:Random generator
  70. 70. Стратегия связывания, IOgetName :: IO ()getName = doputStrLn "What is your name?"yourName <- getLineputStr "Hello, "putStrLn (yourName ++ "!")let world0 = getWorldlet (val1, world1) = ioAction1 world0let (val2, world2) = ioAction2 world1
  71. 71. do-нотацияgetName :: IO ()getName = doputStrLn "What is your name?"yourName <- getLineputStr "Hello, "putStrLn (yourName ++ "!")getName =putStrLn "What is your name?">> getLine>>= yourName -> putStr "Hello, ">> putStrLn (yourName ++ "!")
  72. 72. Возвращаемое значениеgetName :: IO StringgetName = doputStrLn "What is your name?"yourName <- getLineputStr "Hello, "putStrLn (yourName ++ "!")return yourNamereturn :: a -> m aa :: Stringm :: IO
  73. 73. Монада Statenewtype State s a = State{runState :: s -> (a, s)}
  74. 74. Монада StatemyFunc :: State Int IntmyFunc = doval <- getput (val - 8)getgetNumber = evalState myFunc 50main = print getNumber
  75. 75. Стратегия связывания, Statelet state1 = evalState 50let (val1, state2) = get state1let ((), state3) = put (val1 - 8) state2let (val2, state4) = get state3
  76. 76. Monad transformers?Зачем это надо?Монада 2Монада 1
  77. 77. Monad transformers?Зачем это надо?Монада 2Монада 1
  78. 78. State + IOdata GS = GS { worldMap :: [Location], currentLocation :: Location, welded :: Bool, bucketFull :: Bool }deriving (Show)newtype GameState a = GameState{ runGameState :: StateT GS IO a }
  79. 79. State + IOrun :: GameState Resultrun = dot <- get-- read a command from the userio . putStr $ "> "io . hFlush $ stdoutline <- io getLineresult <- case parseCommand line ofNothing -> write "Invalid command!" >> continueJust cmd -> do...........
  80. 80. Named + IO-- Int-named IO calculations:intNamedFunc :: NamedT Int IO IntintNamedFunc = doname <- getNamereturn nametestIntNamed :: IO ()testIntNamed = doname <- evalNamedT intNamedFunc 1print name -- You got output: 1
  81. 81. Спасибо за внимание!HaskellАлександр Гранинgraninas@gmail.com
  82. 82. HaskellScalaClojure...Want more?PLUGIN!!!
  83. 83. FUNctionIts all Haskell is about
  84. 84. Lambda The Gathering
  85. 85. Lambda Lifter
  86. 86. http://bit.ly/17CyYFjHaskell Links
  87. 87. http://hackage.haskell.org/packages/hackage.htmlHackage - репозиторий библиотек
  88. 88. Haskell Platform● Компилятор GHC● Интерпретатор GHCi● Базовые библиотеки● Пакетный менеджерCabal● Документирование -Haddock● MinGW (Windows) http://www.haskell.org/platform/
  89. 89. http://habrahabr.ru/company/selectel/blog/135858/Success Stories
  90. 90. Success StoriesWantmore?http://www.haskell.org/haskellwiki/Haskell_in_industry
  91. 91. Класс типов Monadclass Monad m where(>>=) :: m a -> (a -> m b) -> m b(>>) :: m a -> m b -> m breturn :: a -> m a
  92. 92. Монада Named -именованные вычисленияdata Named n a = Named{ runNamed :: (n -> a) }instance Monad (Named n) wherereturn x = Named (_ -> x)x >>= f = Named (name -> leta = runNamed x namein runNamed (f a) name)

×