Как мне изменить мой класс Queue, чтобы позволить пользователям создавать пустые очереди неопределенного типа в F#?
Я создал неизменный Queue
в 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([], [])
Я хочу создать экземпляр пустой Queue
Однако я получаю исключение ограничения значения:
> let test = Queue.empty;;
let test = Queue.empty;;
----^^^^
C: \ Documents and Settings \ juliet \ Локальные настройки \Temp\stdin(5,5): ошибка FS0030: ограничение значения. Значение 'test' было определено как имеющее универсальный тип val test: Queue<'_ a> Либо определите' test 'как простой термин данных, сделайте его функцией с явными аргументами или, если вы не планируете, чтобы он был универсальным, добавьте аннотацию типа.
По сути, я хочу, чтобы такая же функциональность была Set
модуль, который позволяет мне написать:
> let test = Set.empty;;
val test : Set<'a>
Как я могу изменить мой Queue
класс, чтобы позволить пользователям создавать пустые очереди?
1 ответ
Вам нужно использовать GeneralizableValueAttribute, а-ля:
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>
Вы можете прочитать немного больше об этом в спецификации языка.