Como definir o tipo IntsWithoutZero em f #

5

Recentemente, vi um ótimo vídeo de Scott Wlaschin sobre padrões em programação funcional. Ele dá um exemplo de dividir um número. Em f #, usaríamos int option para o resultado lidar com divisão por zero de uma maneira funcional e funcional.

Como outra possibilidade, ele menciona a criação de um tipo que não permitiria 0 como um valor válido. Vamos dizer IntsWithoutZero . Como poderíamos definir esse tipo de "funcionalmente"?

Sei como faria isso com a abordagem OO (por exemplo, escreva uma classe IntsWithoutZero e desative 0 durante a construção).

    
por Grzegorz Sławecki 03.06.2015 / 23:32
fonte

2 respostas

7

Eu usaria um tipo de união de caso único para quebrar o inteiro.

Eu colocaria o tipo em seu próprio módulo e acessaria através de métodos factory e getter da seguinte forma:

    module IntsWithoutZero =
        // make the type constructor private
        type T = private IntsWithoutZero of int

        // factory that can apply the constraints
        let create value =
            // do check for zero here
            match value with
                | 0 -> None
                | _ -> IntsWithoutZero(value) |> Some

        // a method to extract the private data
        let value (IntsWithoutZero v) = v

    // ================== later in the code ==================
    // create the type
    let myInt = 5 |> IntsWithoutZero.create

    // ================== later when used ==================
    let myDividedValue =
        match myInt with
            | None -> None
            | Some(v) -> 
                // get value out
                let d = (v |> IntsWithoutZero.value)
                // do something zero cannot do
                Some(10 / d)

Se você quiser evitar option , alternativamente, você pode lançar uma exceção no método IntsWithoutZero.create se o usuário fornecer zero como um parâmetro.

Aqui está uma postagem no blog de Scott que faz um trabalho muito melhor explicando esse conceito:

link

Espero que isso ajude!

    
por 04.06.2015 / 04:14
fonte
1

I know how I'd do it with OO approach (e.g. write a IntWihtoutZero class and disallow 0 during construction).

Você faz da mesma maneira: oculta o construtor de dados e expõe apenas uma função que verifica se o inteiro é maior que 0.

    
por 03.06.2015 / 23:47
fonte

Tags