На этот вопрос сложно ответить без примера
Если у вас есть взаимно рекурсивные типы, которые не имеют членов, то типам не нужно знать о функциях (поэтому вы можете сначала определить типы, а затем функции).
Если у вас есть взаимно рекурсивные типы, которые имеют функции в качестве членов, то члены могут видеть друг друга (по типам), и у вас все будет в порядке
Единственный сложный случай - это когда у вас есть взаимно рекурсивные типы, взаимно рекурсивные функции, и вы также хотите представить некоторые функции в качестве членов. Тогда вы можете использовать расширения типа:
// Declare mutually recursive types 'A' and 'B'
type A(parent:option<B>) =
member x.Parent = parent
and B(parent:option<A>) =
member x.Parent = parent
// Declare mutually recursive functions 'countA' and 'countB'
let rec countA (a:A) =
match a.Parent with None -> 0 | Some b -> (countB b) + 1
and countB (b:B) =
match b.Parent with None -> 0 | Some a -> (countA a) + 1
// Add the two functions as members of the types
type A with
member x.Count = countA x
type B with
member x.Count = countB x
В этом случае вы можете просто сделать countA
и countB
членами двух типов, потому что это будет проще, но если у вас есть более сложный код, который вы хотите написать как функции, то это вариант .
Если все написано в одном модуле (в одном файле), то компилятор F # компилирует расширения типов как стандартные члены экземпляра (так что с точки зрения C # это выглядит как обычный тип). Если вы объявите расширения в отдельном модуле, они будут скомпилированы как специфичные для F # методы расширения.