f# mutual-recursion

f# - ¿Cómo tener dos métodos llamando el uno al otro?



mutual-recursion (4)

Funciones declaradas a través de let

let rec a () = b () and b () = ()

Estas son funciones mutuamente recursivas .

Métodos dentro del mismo tipo

type T () = member t.A () = t.B() member t.B () = ()

Esto es trivial; simplemente funciona. Sin embargo, tenga en cuenta el comentario de Abel.

Métodos dentro de diferentes tipos

type TypeA () = member t.A (b : TypeB) = b.B() and TypeB () = member b.B () = ()

Esto usa el type ... and sintaxis para tipos mutuamente recursivos .

Notas

Normalmente, and solo se usa si las llamadas se producen en ambas direcciones. De lo contrario, puede ser mejor reordenar las declaraciones para que la función llamada sea lo primero. A menudo, es útil para la inferencia de tipos y la legibilidad evitar las dependencias circulares, y no implicarlas donde no se usan.

Propongo editar la pregunta para pedir funciones en general o para pedir diferentes tipos (en cuyo caso eliminaría los primeros dos casos de esta respuesta). Los métodos generalmente se consideran un subconjunto de funciones, que es el término matemático general. Sin embargo, todas las funciones F # son técnicamente métodos CLI , ya que es a lo que están compilados. Como está, no está claro lo que la pregunta está pidiendo, pero asumo por la respuesta aceptada que no solo pide métodos, como implicaría el título.

Estoy un poco confundido en cuanto a cómo obtener dos métodos para llamarse entre sí (es decir, tener A() llamar a B() y B() llamar a A() ). Parece que F # solo ''ve'' el método después de haberlo encontrado en el código, por lo que si no lo ha hecho, solo dice que no se ha definido el valor o el constructor .

¿Me estoy perdiendo algo muy básico aquí?



Como la pregunta es sobre métodos y la respuesta de Brian es sobre funciones, tal vez sea útil señalar que puede usar una sintaxis similar para los tipos:

type A() = let b = new B() member x.MethodA() = b.MethodB() and B() = member x.MethodB() = ()

Tenga en cuenta también que los miembros son ''let rec'' por defecto (de hecho, no creo que puedan ser recursivos).


F # 4.1 introduce módulos recursivos y espacios de nombres mutuamente recursivos .

Estas son una alternativa a la palabra clave and .

module rec PingPong = // <------ rec keyword here. let pong() = printfn "pong" ping() let ping () = printfn "ping" pong()

La palabra clave rec define módulos y espacios de nombres que "permiten que todos los códigos contenidos sean mutuamente recursivos".