Я думаю, что это известное ограничение F#, но я не смог найти хороших обходных путей…
Итак, вот код (я старался сделать его как можно проще, поэтому, вероятно, он выглядит бессмысленным):
[<ReflectedDefinition>]
type Human (makeAName: unit -> string) as self =
let mutable cats : Cat array = [| |]
do
// get a cat
cats <- Array.append cats [| new Cat (self, makeAName ()) |]
member this.Cats = cats
and
[<ReflectedDefinition>]
Cat (owner : Human, name : string) = class end
Компилятор говорит:
ошибка FS0452: цитаты не могут содержать встроенный ассемблерный код или сопоставление шаблонов в массивах
На самом деле это комбинация as self
и получателя свойств массива, которая все ломает.
Пункты здесь:
- Я действительно хочу использовать массивы, потому что хочу, чтобы WebSharper переводил мои коллекции в массивы JavaSript.
- Мне действительно нужен самоидентификатор в конструкторах.
- Мне очень нужны классы (т.е. функциональный стиль не сработает).
- Самоидентификаторы для каждого метода (
member this.Foo
) работают нормально.
Один обходной путь, который я могу придумать, — сделать конструкторы закрытыми и использовать статические методы для создания объектов. Таким образом, мне не нужно as self
. Но это просто глупо.
Есть ли лучшие варианты?
Обновление:
Вот еще более простой пример:
[<ReflectedDefinition>]
type User (uid: int) as self =
let ROOT_UID = 0
member this.isRoot = (uid = ROOT_UID)
С as self
я даже не могу определить константу класса. Ну, это вообще-то отдельный вопрос, но я задам его здесь: как мне определить константу класса в данном конкретном случае?