Tutorial :How should I modify my Queue class to allow users to create empty queues of unspecified type in F#?



Question:

I have created an immutable Queue in F# as follows:

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([], [])  

I want to create an instance of an empty Queue, however I get a value-restriction exception:

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

C:\Documents and Settings\juliet\Local Settings\Temp\stdin(5,5): error FS0030: Value restriction. The value 'test' has been inferred to have generic type val test : Queue<'_a> Either define 'test' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.

Basically, I want the same kind of functionality seen in the Set module which allows me to write:

> let test = Set.empty;;    val test : Set<'a>  

How can I modify my Queue class to allow users to create empty queues?


Solution:1

You need to use GeneralizableValueAttribute, a 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>  

You can read a little more about it in the language spec.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »