Как разрешить ошибки ссылок типа F #? - PullRequest
6 голосов
/ 11 мая 2009

Я просматривал свои книги и гуглял до тех пор, пока у меня не закончились поисковые запросы, но я все еще не могу найти пример или ответ на эту проблему:

Следующий код не компилируется, поскольку тип Effect и тип Affect не были объявлены во время объявления Entity. Так что я не понимаю, как это обойти.

В C ++ эта проблема решается с помощью объявления прототипа в h-файлах и последующего включения h-файла. В C # это никогда не проблема. Так как же это разрешается в F #?

#light
type Entity = 
    { 
        Name:string; 
        Affects:List<Affect>; //Compile error: The type Affect is not defined
        Effects:List<Effect>; //Compile error: the type Effect is not defined
    }

type Effect = 
    { 
        Name:string; 
        //A function pointer for a method that takes an Entity and returns an Entity
        ApplyEffect:Entity -> Entity;
    }

type Affect = 
    { 
        Name:string; 
        //A List of Effects that are applied by this Affect Object
        EffectList:List<Effect>; 
        //A function pointer to return an Entity modified by the listed Effects
        ApplyAffect:Entity->Entity;
    }

Основная цель здесь состоит в том, чтобы объект типа Entity должен был иметь возможность перечислять эффекты, которые он может применять к объектам типа Entity. Сущность также может перечислить эффекты, которые были применены к ней. Таким образом, «текущее» состояние объекта можно найти, сложив все эффекты с исходным состоянием объекта.

Спасибо за ваше время,

- Адам Ленда

1 Ответ

13 голосов
/ 11 мая 2009

Я считаю, что это правильный ответ:

http://langexplr.blogspot.com/2008/02/defining-mutually-recursive-classes-in.html

так ...

type Entity = 
    { 
        Name:string; 
        Affects:List<Affect>; 
        Effects:List<Effect>; 
    }
and Effect = 
    { 
        Name:string; 
        ApplyEffect:Entity -> Entity;
    }
and  Affect = 
    { 
        Name:string; 
        EffectList:List<Effect>; 
        ApplyAffect:Entity->Entity;
    }
...