• Save
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Haskell Lite - presentation for DevDay about Haskell language

on

  • 533 views

Presentation about Haskell programming language.

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

Statistics

Views

Total Views
533
Views on SlideShare
533
Embed Views
0

Actions

Likes
1
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Haskell Lite - presentation for DevDay about Haskell language Presentation Transcript

  • 1. HaskellАлександр Гранинgraninas@gmail.com
  • 2. О чем доклад?● Часть 1. Ликбез по ФП и Haskell○ Функциональное программирование○ Язык Haskell. Применимость языка○ Язык Haskell. Основы○ Инструменты разработчика● Часть 2. Haskell: We need to go deeper○ Обработка данных: NgnTrafficParser○ XML и Domain Specific Languages○ Parsec, HaXml, GenXml● Часть 3. Немного хардкора○ Монады!!!
  • 3. Программирование:● Императивное● Объектно-ориентированное● Функциональное● Логическое● Декларативное
  • 4. (println "Hello World!")printfn "Hello World!"io:format("Hello, World!~n").putStrLn "Hello World!"println("Hello World!")
  • 5. Функциональноепрограммирование?
  • 6. Функциональноепрограммирование● Все есть функция● ...● ...● ...● ...● ...
  • 7. Функциональноепрограммирование● Все есть функция● Рекурсия● ...● ...● ...● ...
  • 8. Функциональноепрограммирование● Все есть функция● Рекурсия● Функции высшихпорядков● ...● ...● ...
  • 9. Функциональноепрограммированиеa := 1a := 2DO NOT CHANGE!The immutability is with you● Все есть функция● Рекурсия● Функции высшихпорядков● Иммутабельностьданных● ...● ...
  • 10. Функциональноепрограммирование● Все есть функция● Рекурсия● Функции высшихпорядков● Иммутабельностьданных● Чистые функции● ...
  • 11. Функциональноепрограммирование● Все есть функция● Рекурсия● Функции высшихпорядков● Иммутабельностьданных● Чистые функции● Нет побочныхэффектов
  • 12. Язык Haskell?
  • 13. Язык HaskellHaskell - это...● Чистый функциональный,● строго статически типизированный,● кроссплатформенный,● компилируемый язык● общего назначения● с ленивой семантикой● и автоматическим выводом типов.
  • 14. Краткая история Haskell● В честь Хаскеля Карри● GHC: Саймон Пейтон Джонс● Семейство языков ML● Прародитель - Miranda● 1990 год - Haskell 1.0● 1998 год - Haskell 98● 2009 год - Haskell 2010«Доказательство —это программа, адоказываемаяформула — это типпрограммы»(c)MiranLipovača
  • 15. Где Haskell плох:● Системное программирование● Real-time системы● GUI
  • 16. Где Haskell хорош:● Надежность кода
  • 17. ● Надежность кода● Domain Specific LanguagesAbstract SyntaxTreeCode baseГде Haskell хорош:
  • 18. ● Надежность кода● Domain Specific Languages● Безопасный параллелизмГде Haskell хорош:
  • 19. ● Надежность кода● Domain Specific Languages● Безопасный параллелизм● Обработка данныхТелекомы:TrafficParserГде Haskell хорош:
  • 20. ● Надежность кода● Domain Specific Languages● Безопасный параллелизм● Обработка данных● ПарсингГде Haskell хорош:NameDescriptionBody TypeXMLDSL
  • 21. Haskell - не мэйнстрим?..
  • 22. Причины непопулярности● Pascal, C, C++, Java, C# - в вузах● Традиционное мировоззрение очень сильно● Заработать на Haskell очень трудно● Мифы и стереотипы"Избегать успеха любой ценой."Саймон Пейтон Джонс
  • 23. Язык Haskell: Основы
  • 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. fib 0 = 0fib 1 = 1fib n = fib (n-1) + fib (n-2)fact 0 = 1fact n = fact (n-1) * nСопоставление с образцомФункции,аргументы -lowerCamelCase
  • 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. fact :: Word -> Wordreplicate :: Int -> a -> [a]map :: (a -> b) -> [a] -> [b](+) :: Int -> Int -> Intadd :: Int -> Int -> IntСистема типов
  • 28. Списки. Кортежиphonebook :: [(String, String)]phonebook =[ ("Bob", "953 777-44-45"), ("Fred", "919 33-555-11"), ("Alice", "383 11111111"), ("Jane", "964 4000004") ]
  • 29. Списки. Кортежиtype PhoneBook = [(String, String)]validate :: PhoneBook -> PhoneBookvalidate book= map addPrefix bookaddPrefix :: (String, String) -> (String, String)addPrefix (name, phone) = (name, "+7 " ++ phone)
  • 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. Генераторы списков(c) Miran Lipovača http://learnyouahaskell.com/
  • 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. 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. Алгебраические типы данныхdata Bool = True| FalseТип Конструкторы
  • 35. Алгебраические типы данныхdata STree= Tip| Branch{leftBranch :: STree,value :: Int,rightBranch :: STree}
  • 36. Сопоставление с образцомheight :: STree -> Intheight Tip = 0height (Branch lt _ rt) = 1 + max (height lt) (height rt)53 71 4
  • 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. Инструменты разработки
  • 39. Haskell Platform● Компилятор GHC● Интерпретатор GHCi● Базовые библиотеки● Пакетный менеджерCabal● Документирование -Haddock● MinGW (Windows) http://www.haskell.org/platform/
  • 40. Glasgow Haskell CompilerКомпиляция:ghc --make FizzBuzz.hsghc --make -O2 FizzBuzz.hsghc --make -O2 -threaded FizzBuzz.hsВыполнение:runghc FizzBuzz.hs
  • 41. REPL - GHCi(GHC interpreter)ReadEvalPrintLoop
  • 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. Hackage - репозиторий библиотек
  • 44. Библиотеки и программы● xmonad - тайловый оконный менеджер● Parsec - комбинаторные парсеры● HaXmL, HXT - обработка XML● darcs - система контроля версий● Yesod - RESTful веб-фреймворк● QuickCheck - тестирование кода● House, Kinetic - операционные системы● Всевозможные эффективные коллекции● OpenGL, OpenAL, OpenCL биндинги● ... несколько игр и многое другое
  • 45. IDE
  • 46. EclipseFP
  • 47. Leksah
  • 48. SublimeHaskell
  • 49. Wantmore?
  • 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. NGN Traffic ParserBillingMerge FilesProcess dataMS SQL DTS
  • 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. 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. XML и Domain Specific Languages
  • 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. Тестирование политикиАлгоритмы тестирования:Безопасность обеспечена?НетИсправляемдырыДаОК, запускаем!!Policy.xml
  • 57. Policy.xmlXML?!. Сложно! Хочу DSL!Алгоритмы тестирования:Безопасность обеспечена?НетИсправляемдырыДаОК, запускаем!!MyPolicy.dsl
  • 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. Архитектура DSL <-> XMLPolicy.xmlPolicy.dslPolicy ASTHaXmlGenXmlCustom writerParsecDSL ASTTranslator
  • 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. 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. Связь с БНФ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. 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. 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. А теперь - хардкор!!!
  • 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. data Predicate = NotInList [ByteString]| InList [ByteString]| Like [ByteString]| LengthLess Intderiving (Eq, Show, Read)Классы типов -"интерфейсы" на стероидах
  • 68. Монада IO:Безопасный ввод-выод
  • 69. let rndGen1 = mkStdGen 100let (val1, rndGen2) = random rndGen1let (val2, rndGen3) = random rndGen2Отправной пример:Random generator
  • 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. 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. Возвращаемое значениеgetName :: IO StringgetName = doputStrLn "What is your name?"yourName <- getLineputStr "Hello, "putStrLn (yourName ++ "!")return yourNamereturn :: a -> m aa :: Stringm :: IO
  • 73. Монада Statenewtype State s a = State{runState :: s -> (a, s)}
  • 74. Монада StatemyFunc :: State Int IntmyFunc = doval <- getput (val - 8)getgetNumber = evalState myFunc 50main = print getNumber
  • 75. Стратегия связывания, Statelet state1 = evalState 50let (val1, state2) = get state1let ((), state3) = put (val1 - 8) state2let (val2, state4) = get state3
  • 76. Monad transformers?Зачем это надо?Монада 2Монада 1
  • 77. Monad transformers?Зачем это надо?Монада 2Монада 1
  • 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. 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. 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. Спасибо за внимание!HaskellАлександр Гранинgraninas@gmail.com
  • 82. HaskellScalaClojure...Want more?PLUGIN!!!
  • 83. FUNctionIts all Haskell is about
  • 84. Lambda The Gathering
  • 85. Lambda Lifter
  • 86. http://bit.ly/17CyYFjHaskell Links
  • 87. http://hackage.haskell.org/packages/hackage.htmlHackage - репозиторий библиотек
  • 88. Haskell Platform● Компилятор GHC● Интерпретатор GHCi● Базовые библиотеки● Пакетный менеджерCabal● Документирование -Haddock● MinGW (Windows) http://www.haskell.org/platform/
  • 89. http://habrahabr.ru/company/selectel/blog/135858/Success Stories
  • 90. Success StoriesWantmore?http://www.haskell.org/haskellwiki/Haskell_in_industry
  • 91. Класс типов Monadclass Monad m where(>>=) :: m a -> (a -> m b) -> m b(>>) :: m a -> m b -> m breturn :: a -> m a
  • 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)