Pergunta

Estou tentando criar vários métodos de extensão para um tipo genérico vinculado a parâmetros de tipo genérico específico em F#, mas o idioma não parece estar me permitindo:

O que eu quero fazer é algo como o seguinte:

type IEnumerable<int> with
    member this.foo =
        this.ToString()

No entanto, isso me dá o erro do compilador (sublinhando o int palavra -chave):

Identificador inesperado em nome de tipo. Operador de infix esperado, símbolo de cotação ou outro token.

A seguir faz trabalho, embora ele não vincule especificamente o parâmetro de tipo genérico a int, como eu quero:

type IEnumerable<'a> with
    member this.foo =
        this.ToString()

Existe alguma maneira de atingir esse objetivo em F# - talvez estou apenas usando a sintaxe errada? Caso contrário, eu apreciaria se alguém pudesse sugerir uma solução alternativa, talvez usando restrições de tipo em algum lugar.

Foi útil?

Solução

Isso não é possível na versão atual do F#, infelizmente. Veja a pergunta relacionada aqui.

Outras dicas

Os métodos de extensão genérica estão agora disponíveis no F# 3.1:

open System.Runtime.CompilerServices
open System.Collections.Generic

[<Extension>]
type Utils () =
    [<Extension>]
    static member inline Abc(obj: IEnumerable<int>) = obj.ToString()

printfn "%A" ([1..10].Abc())

Bem, você pode usar restrições - mas não com tipos selados como o Int.

type IEnumerable<'a when 'a :> InheritableType> =
member this.Blah =
    this.ToString()

Hum...

Para ajudar outras pessoas que procuram soluções semelhantes, aqui está um exemplo mostrando como usar métodos de extensão genérica com restrições de tipo. No exemplo abaixo, existe uma restrição de tipo que exige que o argumento de tipo passado exponha um construtor padrão. Isso é feito usando o [<CLIMutable>] atributo aplicado ao Order registro. Além disso, estou construindo o resultado do método para o tipo aprovado.

Para usar o método de extensão, você deve especificar o tipo que deseja usar. Observe que também estou estendendo uma interface de dicionário genérico.

[<Extension>]
type ExtensionMethds () = 

    [<Extension>]
    static member inline toObject<'T when 'T: (new: unit -> 'T)> (dic: IDictionary<string,obj>): 'T =
        let instance = new 'T()
        // todo: set properties via reflection using the dictionary passed in
        instance


[<CLIMutable>]
type Order = {id: int}

let usage = 
    let dictionaryWithDataFromDb = dict ["id","1" :> obj] 
    let theOrder = dictionaryWithDataFromDb.toObject<Order>()
    theOrder
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top