2009-05-29 1 views
6

J'ai créé un Queue immuable en F # comme suit:Comment dois-je modifier ma classe de file d'attente pour permettre aux utilisateurs de créer des files d'attente vides de type non spécifié dans 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([], []) 

Je veux créer une instance d'un vide Queue, mais je reçois une exception valeur de restriction:

> let test = Queue.empty;; 

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

C : \ Documents and Settings \ juliet \ Paramètres locaux \ Temp \ stdin (5,5): erreur FS0030: Restriction de valeur. La valeur 'test' a été déduite pour avoir le type générique val test: File d'attente < '_a> Soit définir' test 'comme un simple terme de données, en faire une fonction avec des arguments explicites ou, si vous ne l'avez pas prévu pour être générique, ajoutez une annotation de type.

Fondamentalement, je veux le même genre de fonctionnalités dans le module de Set qui me permet d'écrire:

> let test = Set.empty;; 

val test : Set<'a> 

Comment puis-je modifier mon Queue classe pour permettre aux utilisateurs de créer des files d'attente vides?

+2

* pojh * Cela devrait être un CW :) –

+2

Downvoters: veuillez fournir une raison pour laquelle vous avez downvoted cette question. – Juliet

+0

@Princess: Downvoting est anonyme. Pourquoi avez-vous besoin de savoir qui l'a fait? – GEOCHET

Répondre

6

Vous devez utiliser GeneralizableValueAttribute, à la:

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> 

Vous pouvez lire un peu plus à ce sujet dans le language spec.

+0

J'aurais juré que j'avais écrit exactement ça, mais on dirait que vous l'avez mieux écrit. Très appréciée :) – Juliet

Questions connexes