Novidades no F# 4.7

O F# 4.7 adiciona várias melhorias à linguagem F#.

Introdução

O F# 4.7 está disponível em todas as distribuições do .NET Core e nas ferramentas do Visual Studio. Introdução à linguagem F# para saber mais.

Versão da linguagem

O compilador de F# 4.7 apresenta a capacidade de definir sua versão de linguagem efetiva por meio de uma propriedade em seu arquivo de projeto:

<PropertyGroup>
    <LangVersion>preview</LangVersion>
</PropertyGroup>

É possível defini-la para os valores 4.6, 4.7, latest e preview. O padrão é latest.

Se você defini-la como preview, o compilador ativará todas as versões prévias de recursos de F# implementadas nele.

Resultados implícitos

Você não precisa mais aplicar a palavra-chave yield em matrizes, listas, sequências ou expressões de computação em que o tipo pode ser inferido. No exemplo a seguir, ambas as expressões exigiam a instrução yield para cada entrada antes do F# 4.7:

let s = seq { 1; 2; 3; 4; 5 }

let daysOfWeek includeWeekend =
    [
        "Monday"
        "Tuesday"
        "Wednesday"
        "Thursday"
        "Friday"
        if includeWeekend then
            "Saturday"
            "Sunday"
    ]

Se você introduzir uma única palavra-chave yield, todos os outros itens também deverão ter yield aplicado a ela.

Os resultados implícitos não são ativados quando são usados em uma expressão que também utiliza yield! para fazer algo como o nivelamento de uma sequência. No momento, você deve continuar a usar yield nesses casos.

Identificadores curinga

No código em F# que envolve classes, o auto-identificador precisa ser sempre explícito em declarações de membro. No entanto, nos casos em que o auto-identificador nunca é usado, tem sido uma convenção tradicional usar um sublinhado duplo para indicar um auto-identificador sem nome. Agora é possível usar um único sublinhado:

type C() =
    member _.M() = ()

Isso também se aplica a loops for:

for _ in 1..10 do printfn "Hello!"

Relaxamentos de recuo

Antes do F# 4.7, os requisitos de recuo de argumentos de construtor primário e membro estático exigiam recuo excessivo. Agora eles exigem apenas um único escopo de recuo:

type OffsideCheck(a:int,
    b:int, c:int,
    d:int) = class end

type C() =
    static member M(a:int,
        b:int, c:int,
        d:int) = 1