1

How do we make two functions mutually aware of each other? For instance, in the following code, how can we make ping and pong call each other?

module PingPong = 

    let pong = 
        printfn "pong"
        ping 
        // error: The value or constructor 'ping' is not defined.

    let ping = 
        printfn "ping"
        pong

    [<EntryPoint>]
    let main argv = 
        ping
        0

Edit:

Since writing the question, we've found that as of F# 4.1 there is now the module rec keyword. Simply using module rec PingPong... though means that on line 3 we receive this new error:

error FS0031: This value will be eventually evaluated as part of its own definition. You may need to make the value lazy or a function. Value 'pong' will evaluate 'ping' will evaluate 'pong'.

Edit:

After doing more research, we learned the difference between values and functions. We were able to make the following work like this:

module rec PingPong = 

    let pong() = 
        printfn "pong"
        ping() 

    let ping () = 
        printfn "ping"
        pong()

    [<EntryPoint>]
    let main _ = 
        ping()
        0

So, as a follow up question for those who might now the answer, how would we have made two functions mutually in scope before F# 4.1 introduced recursive modules?

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467

1 Answers1

4

You can make mutually recursive definitions like this:

let pong = 
    printfn "pong"
    ping
and ping = 
    printfn "ping"
    pong

But your lets aren't functions. And you'd need to mark pong as recursive with rec:

let rec pong x = 
    printfn "pong"
    ping (x + 2)
and ping x = 
    printfn "ping"
    pong (x + 1)

This program doesn't really "work", but it shows the concept. Here's something that will eventually finish:

let rec pong x = 
    printfn "pong"
    ping (x - 2)
and ping x = 
    printfn "ping"
    match x with
    | 1 -> 1
    | 2 -> 1
    | x -> pong (x + 1)

> pong 5;;
pong
ping
pong
ping
val it : int = 1
Taylor Wood
  • 15,886
  • 1
  • 20
  • 37