2009-05-29 11 views
6

He creado una inmutable Queue en F # como sigue:¿Cómo debo modificar mi clase Queue para permitir a los usuarios crear colas vacías de tipo no especificado en F #?

type Queue<'a>(f : 'a list, r : 'a list) =  
    let check = function 
     | [], r -> Queue(List.rev r, []) 
     | f, r -> Queue(f, r) 

    member this.hd = 
     match f with 
     | [] -> failwith "empty" 
     | hd :: tl -> hd 

    member this.tl = 
     match f, r with 
     | [], _ -> failwith "empty" 
     | hd::f, r -> check(f, r) 

    member this.add(x) = check(f, x::r) 

    static member empty : Queue<'a> = Queue([], []) 

que quieren crear una instancia de un vacío Queue, sin embargo recibo una excepción valor restricción:

> let test = Queue.empty;; 

    let test = Queue.empty;; 
    ----^^^^ 

C : \ Documents and Settings \ juliet \ Configuración local \ Temp \ stdin (5,5): error FS0030: Restricción de valores. Se ha deducido que el valor 'test' tiene el tipo genérico val test: Queue < '_a> Defina' test 'como un simple término de datos, haga que sea una función con argumentos explícitos o, si no tiene la intención de hacerlo para ser genérico, agregue una anotación de tipo.

Básicamente, quiero que el mismo tipo de funcionalidad se ve en el módulo Set la que me permite escribir:

> let test = Set.empty;; 

val test : Set<'a> 

¿Cómo puedo modificar mi clase Queue para permitir a los usuarios crear colas vacías?

+2

* pojh * Esto debería ser un CW :) –

+2

Downvoters: indique por qué ha votado negativamente esta pregunta. – Juliet

+0

@Princess: Downvoting es anónimo. ¿Por qué necesitas saber quién lo hizo? – GEOCHET

Respuesta

6

Es necesario utilizar GeneralizableValueAttribute, al estilo de:

type Queue<'a>(f : 'a list, r : 'a list) = // ' 
    let check = function 
     | [], r -> Queue(List.rev r, []) 
     | f, r -> Queue(f, r) 

    member this.hd = 
     match f with 
     | [] -> failwith "empty" 
     | hd :: tl -> hd 

    member this.tl = 
     match f, r with 
     | [], _ -> failwith "empty" 
     | hd::f, r -> check(f, r) 

    member this.add(x) = check(f, x::r) 
module Queue =  
    [<GeneralizableValue>] 
    let empty<'T> : Queue<'T> = Queue<'T>([], []) // ' 

let test = Queue.empty 
let x = test.add(1)  // x is Queue<int> 
let y = test.add("two") // y is Queue<string> 

se puede leer un poco más sobre él en el language spec.

+0

Podría haber jurado que había escrito exactamente eso, pero parece que lo has escrito mejor. Muy apreciado :) – Juliet

Cuestiones relacionadas