Неизвестная потребность в аннотации типа или литье
Я знаю, что я должен упустить что-то действительно очевидное здесь. B.GetInstance().Call()
генерирует ошибку: поиск объекта неопределенного типа на основе информации до этой точки программы. Аннотации типа могут потребоваться до этой точки программы, чтобы ограничить тип объекта. Это может позволить разрешить поиск.
Я использую v1.9.9.9.
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() = new B()
member x.Call() = ()
Я только что обнаружил, что это работает: (B.GetInstance() :> B).Call()
Любая идея, почему актер нужен?
Ответы
Ответ 1
Часто, когда у вас есть рекурсивный набор методов, типы которых выводятся, F # нуждается в помощи. Более приятной альтернативой было бы аннотировать определение B.GetInstance
:
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() : B = new B()
member x.Call() = ()
Я считаю, что причина, по которой вы столкнулись с этой проблемой, заключается в том, что F # пытается решить все выводимые типы для всех методов в и B одновременно (потому что они определены как взаимно-рекурсивные типы), и это приводит к проблемам, но, возможно, кому-то из команды F # будет взвешиваться.
Ответ 2
Краткое краткое описание состоит в том, что в рекурсивной группе (например, члены одного типа или члены рекурсивных типов, как у нас здесь) F # читает объявления в порядке слева направо сверху вниз, за которыми следуют определения в порядке слева направо сверху вниз. Поэтому в этом случае, когда он достигает определения A.Call
, он еще не прочитал определение B.GetInstance
и, следовательно, (пока!) Не знает, что тип возврата GetInstance
будет B
.
Ответ Keith называет это для этой ситуации, вы можете предоставить аннотацию типа, чтобы указать тип возврата GetInstance
в своем объявлении.
См
Принудительно вызывать вывод типа F на дженериках и интерфейсах
для глубокого обсуждения того, что происходит здесь.
Обратите внимание, что в вашей первоначальной попытке вам не нужно "бросать" (потенциально динамическую операцию, используя :>
), вместо этого вы можете просто "аннотировать" (статически объявлять тип, используя :
) чтобы заставить его скомпилировать. Но имеет смысл помещать аннотацию типа в объявление метода для GetInstance
(как правило, предпочитают добавлять аннотации к сигнатурам методов вместо произвольных мест внутри тел).