Теории и практики функционального программирования

  • Published on
    03-Mar-2017

  • View
    175

  • Download
    0

Embed Size (px)

Transcript

  • ?

    5+ dotNet interpraise/

    2+ python freelance/

    2+ I love FP

    dotnetconf, dev2dev/

    it- dev2dev

    2

  • ?

    3

  • ?

    4

  • , ...

    5

  • ?

    6

  • -

    HttpRequest HttpResponse

    7

  • -

    function (HttpRequest) HttpResponse

    8

  • ?

    . .

    !

    9

  • 10

  • SOLID IoC GRASP GangOfFour MVC, MVP, MVVM CQRS EventSourcing DDD ...

    11

  • SOLID IoC GRASP GangOfFour MVC, MVP, MVVM CQRS EventSourcing DDD ...

    Functions Type Composition

    12

  • SOLID IoC GRASP GangOfFour MVC, MVP, MVVM CQRS EventSourcing DDD ...

    Functions Type Composition

    Monads, Monoids...

    13

  • 14

  • 15

  • let value = 5

    let toX10 = fun x -> x * 10

    16

  • let getCalc f x y = fun z -> (f x) + y + z

    let calc = getCalc toX10 1 2

    let result = calc value

    17

  • 18

  • :

    let read (x : string) : int = int(x)

    let mult (x : int) : int = x * x

    let write (x : int) : string = string(x)

    19

  • :

    let readMultWrite1 x = write (mult (read x))

    // x : string -> string

    let readMultWrite2 = read >> mult >> write

    // string -> string

    let readMultWrite3 x = x |> read |> mult |> write

    // x : string -> string20

  • a b b ca c

    21

  • a b b c ... x za z

    22

  • : #

    let (>>) f1 f2 p = f2(f1 p)let (

  • : #

    let (|>) p f = func paramlet (

  • ...

    25

  • !

    26

  • : #

    let add x y = x + y // int -> int -> int

    let add2 = add 2 // int -> int

    let res = add2 2 // val res : int = 4

    27

  • 28

  • #

    type Alias = inttype FunctionAlias = int -> int

    29

  • #

    type Record = { field1 : int; field2 : string }

    30

  • #

    type DiscriminatedUnion = | Variant1 of int | Variant2 of string

    type Enum = | One = 1 | Two = 2 | Three = 3

    31

  • 32

  • :

    type NodeName = stringtype UID = int

    type HierarchyIdentifier = | Plain of UID | Complex of NodeName*HierarchyIdentifier

    33

  • :

    Complex(NodeName * Complex

    (NodeName * Complex(Plain)

    ))

    34

  • 35

  • Interfaces & SRP

    public interface IExchangeRateProvider { ExchangeRate GetRate(Currency currency); }

    public class ExchangeProvider : IExchangeRateProvider { public ExchangeRate GetRate(Currency currency) { // =) } }

    36

  • Interfaces & SRP#

    type IExchangeRateProvider = Currency -> ExchangeRate

    let exchangeRateProvider(currency:Currency):ExchangeRate = // =)

    37

  • DI

    public class BasketCostTranslator : IBasketCostTranslator{ private readonly IExchangeRateProvider _provider;

    public BasketCostTranslator(IExchangeRateProvider p) { // =) }

    public BasketCost TranslateCost(BasketCost cost) { // =) }}

    38

  • DI#di

    type ICostTranslator = BasketCost -> BasketCost

    let costTranslator exchangeProvider basket = // =)

    let translator = costTranslator exchangeRateProvider

    39

  • public class SimpleDeliveryCalculator : IDeliveryCostCalculator{ public DeliveryOffer Calculate(

    IEnumerable purchases) { // do something var packagesCount = CalculatePackagesCount(purchases); // do something }

    protected virtual int CalculatePackagesCount(IEnumerable purchases)

    { // calculation }}

    40

  • public class ComplexDeliveryCalculator: SimpleDeliveryCalculator{ protected override int CalculatePackagesCount(

    IEnumerable purchases) { // "complex" calculation }}

    41

  • #

    let deliveryCalculator packagesCalculator purchases = // do something let packagesCount = packagesCalculator purchases // do something

    let simpleCalculatePackages purchases = // do something

    let complexCalculatePackages purchases = //do something

    let calculator1 = deliveryCalculator simpleCalculatePackageslet calculator2 = deliveryCalculator complexCalculatePackages

    42

  • public class LoggingDecorator : IExchangeRateProvider{ private IExchangeRateProvider _service;

    public LoggingDecorator(IExchangeRateProvider service) { ... }

    public ExchangeRate GetRate(Currency currency) { // log something var result = _service.GetRate(currency); // log something return result; }}

    43

  • #

    let loggingDecorator provider currency = // log something let result = provider currency // log something result

    let provider = loggingDecorator exchangeRateProvider

    44

  • #py

    def logging(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) print(func.__name__, args, kwargs) return res return wrapper

    @loggingdef adder(x, y): return x + y

    adder(1, 2)45

  • -

    46

  • 47

  • #

    let adder x = x + 100

    adder 10 // val it : int = 110adder 10 // val it : int = 110adder 20 // val it : int = 120

    48

  • #

    let memoize (f: 'a -> 'b) = let dict = new Dictionary() let memoized (input: 'a) = match dict.TryGetValue(input) with | true, x -> x | false, _ -> let result = f input dict.Add(input, result) result memoized

    let memAdder = memoize adder49

  • #

    let memoize (f: 'a -> 'b) = let dict = new Dictionary() let memoized (input: 'a) = match dict.TryGetValue(input) with | true, x -> x | false, _ -> let result = f input dict.Add(input, result) result memoized

    let memAdder = memoize adder50

  • #

    let memoize (f: 'a -> 'b) = let dict = new Dictionary() let memoized (input: 'a) = match dict.TryGetValue(input) with | true, x -> x | false, _ -> let result = f input dict.Add(input, result) result memoized

    let memAdder = memoize adder51

  • #

    function (HttpRequest) HttpResponse

    52

  • #

    function (HttpRequest, DbState) HttpResponse

    53

  • #

    https://github.com/Suor/django-cacheops

    54

  • 55

  • #

    let handleRequest = readRequest >> readEntityFromDB >> modifyEntity >> createTaskFromEntity >> writeTaskToMQ >> createResultMessage >> sendMessage

    56

  • 57

  • type Result

    58

  • let handleRequest s = match readRequest s with | Success r -> match readEntityFromDB r with | Success e -> match modifyEntity e with | Success me -> match createTaskFromEntity me with | Success t -> match writeTaskToMQ t with | Success ts -> createResultMessage ts | Error -> Error | Error -> Error | Error -> Error | Error -> Error | Error -> Error 59

  • ?

    60

  • #

    'a Result

  • #

    ('a Result Result

  • let handleRequest s = match readRequest s with | Success r -> match readEntityFromDB r with | Success e -> match modifyEntity e with | Success me -> match createTaskFromEntity me with | Success t -> match writeTaskToMQ t with | Success ts -> createResultMessage ts | Error -> Error | Error -> Error | Error -> Error | Error -> Error | Error -> Error 63

  • #

    let handleRequest s = match readRequest s with | Success r -> match readEntityFromDB r with | Success e -> match modifyEntity e with | Success me -> match createTaskFromEntity me with | Success t -> match writeTaskToMQ t with | Success ts -> createResultMessage ts | Error -> Error | Error -> Error | Error -> Error | Error -> Error | Error -> Error 64

  • #

    let bind f = fun x -> match x with | Success r -> f r | Error -> x

    ('a Result Result

  • #

    let handleRequest = readRequest >> (bind readEntityFromDB) >> (bind modifyEntity) >> (bind createTaskFromEntity) >> (bind writeTaskToMQ) >> (bind createResultMessage)

    66

  • 67

  • ,

    68

  • http://www.intuit.ru/studies/courses/471/327/info

    https://github.com/fsprojects/FSharpx.Extras

    https://github.com/jack-pappas/ExtCore/

    http://fsharpforfunandprofit.com/

    69

    http://www.intuit.ru/studies/courses/471/327/infohttps://github.com/fsprojects/FSharpx.Extrashttps://github.com/jack-pappas/ExtCore/http://fsharpforfunandprofit.com/

  • ?

    70

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

Recommended

View more >