I'm a bit confused as to how to get two method to call each other (i.e., have A() call B() and B() call A()). It seems that F# only 'sees' the method after it's been encountered in code, so if it hasn't, it just says value or constructor has not been defined.
Am I missing something very basic here?
'let rec... and...' is the syntax you seek.
let rec F() =
G()
and G() =
F()
See also Adventures in F# Co-Recursion.
Since the question is about methods, and Brian's answer is about functions, maybe it's useful to point out that you can use a similar syntax for types:
type A() =
let b = new B()
member x.MethodA() = b.MethodB()
and B() =
member x.MethodB() = ()
Note also that members are 'let rec' by default (in fact I don't think they can be not recursive).
F# 4.1 introduces mutually recursive modules and namespaces.
These are an alternative to the and keyword.
module rec PingPong = // <------ rec keyword here.
let pong() =
printfn "pong"
ping()
let ping () =
printfn "ping"
pong()
The rec keyword defines modules and namespaces that "allow for all contained code to be mutually recursive."
Functions declared via let
let rec a () = b ()
and b () = ()
These are mutually recursive functions.
Methods within the same type
type T () =
member t.A () = t.B()
member t.B () = ()
This is trivial; it just works. Note Abel's comment though.
Methods within different types
type TypeA () =
member t.A (b : TypeB) = b.B()
and TypeB () =
member b.B () = ()
This uses the type ... and syntax for mutually recursive types.
Notes
Normally, and is only used if the calls occur in both directions. Otherwise, it may be better to re-order the declarations so that the called function comes first. It is often helpful for type-inference and readability to avoid circular dependencies, and to not imply them where they aren't used.
I propose to edit the question to either ask for functions in general, or to ask for different types (in which case I would remove the first two cases from this answer). Methods are usually considered to be a subset of functions, which is the general mathematical term. However, all F# functions are technically CLI methods, as that is what they are compiled to. As is, it is not clear what the question is asking for, but I assume from the accepted answer that it does not only ask for methods, as the title would imply.
Related
Given the following F# code
type MyClass = class end
type MyWorker1() =
(*1*)member this.DoWork(myObject: MyClass) = ()
(*2*)member this.DoWork(myObjects: MyClass seq) = myObjects |> Seq.iter this.DoWork //Resolves to (*1*)
type MyWorker2() =
(*3*)member this.DoWork(myObject: #MyClass) = ()
(*4*)member this.DoWork(myObjects: #MyClass seq) = myObjects |> Seq.iter this.DoWork //Resolves to (*4*)
in MyWorker2 the call this.DoWork is resolved as recursive call. I expected to behave as in MyWorker1, that is call (*3*).
Can someone explain the reason for this difference?
As already reported by #Gus on Slack, this is likely a bug, good you reported it! Note that it appears to happen only with seq, not with other collection types like array or list. It also doesn't happen when you use let bindings instead of member or static member.
This is probably because let bindings cannot be self-referential unless you add rec. By adding rec, you actually do see the same behavior again, but this time it is expected.
I'm surprised that F# adds an extra constraint as 'a :> seq<'a>, I find this really odd.
Since this is SO, and I'm gonna assume this blocks a certain pattern of coding, here's a workaround. It's a little extra indirection, but if you need the above pattern in real world code, here's how you can do it:
type MyWorker2() =
let doWork1(myObject: #MyClass) = ()
let doWork2(myObjects: seq<#MyClass>) = myObjects |> Seq.iter (fun x -> doWork1 x) //Resolves to (*4*)
member this.DoWork(myObject: #MyClass) = doWork1 myObject
member this.DoWork(myObjects: seq<#MyClass>) = doWork2 myObjects
One observation, if you make the private let-bindings the same name (i.e. just doWork instead of doWork1|2), the issue with the extra type restriction appears on the first DoWork. But this time it makes sense, as the let-bindings shadow one another.
In F# one comes across this sort of thing:
let p = Earth().GetCountry1().GetPopulation()
Sometimes I find myself wanting to separate the argument from the function as is usually done in F#:
let p = ((Earth ()).GetCountry1 ()).GetPopulation ()
which requires many parentheses. Is there a function, or can someone think of one, which can be used in place of the dot operator, which facilitates a more elegant way of maintaining the space between function and argument -- something like this?
let dot method arg obj = obj.method arg
let p = Earth () |> dot GetCountry1 () |> dot GetPopulation ()
(My dot causes a compiler error.)
The original code is perfectly idiomatic F#. There's no need to change it.
However, sometimes you have an F# function pipeline and you need to call a method in the middle of it. The neatest way to do this is with a lambda:
aValue
|> aFunction parameter
|> anotherFunction
|> fun x -> x.Method()
|> oneLastFunction
The function you're trying to write is not possible in a statically typed language. This would need to be added as a language feature, or you can simply use a lambda as shown above.
First off, F# is a multi-paradigm language, so writing code in an OOP style is perfectly valid. If you are consuming C# libraries, this is very common.
I would suggest using the OOP-style (no space before arguments) for the OOP-style code and the functional-style (space after arguments) for the functional-style code.
There is no built-in mechanism for piping members in F#. This could be enabled in the future with the short-hand accessor suggestion or the lenses suggestion.
For now, the quickest solution for the functional-style is to write an anonymous function:
let p =
Earth ()
|> fun x -> x.getCountry1 ()
|> fun x -> x.getPopulation ()
If you do this frequently, it might be best to write a collection of helper functions:
let country1 x =
x.getCountry1 ()
let population x =
x.getPopulation ()
let p =
Earth ()
|> country1
|> population
You could probably implement your dot function using reflection but that would have a run-time overhead, which is probably not worth it.
Is it possible to create methods or stand-alone functions in a computation expression that can later be used by one of the canonical methods of a computation expression?
I want something like this:
type FormletBuilder(ctx : HttpContext) =
let get_int =
match Int32.TryParse (ctx.Request.["foo"]) with
| (true, n) -> Some n
| _ -> None
//similar definitions for get_date, get_non_empty_str, etc...
member x.Bind (read : 'a option, f : 'a -> option 'a) =
match read with
| Some x -> f(x)
| None -> None
member x.Return (obj) = Some obj
member x.Zero () = None
let person = formlet ctx {
let! id = get_int "id"
let! name = get_non_empty_str "fullname"
return Person(id, name)
}
But the compiler complains that get_int is not defined.
let bindings in class definitions are always private. You can define a member instead.
For an easy solution, you could do:
let formlet = FormletBuilder(ctx)
let person = formlet {
let! id = formlet.get_int "id"
...
}
I understand now that what you actually want is a maybe monad, and the workflow argument is there just to make use of some syntactic sugar? If so, there are a couple other things you can consider doing:
Go Haskell on it all the way and implement a MaybeReader monad, so that both the maybe and the reader parts of it are explicit in type,
Put the sugar away - I understand you don't actually need the context in any core builder members? If so, than maybe it had no business being an argument to the builder in the first place. Have a 'clean' maybe monad, move get_int etc. into a proper module and have them take HttpContext explicitly as an argument.
If you're using F# 3.0 or later, you can define get_int etc. as custom operations of the workflow, which should effectively give you the nice syntax you want to have. Here's a good post about it by Tomas Petricek.
Combine 2. and 3. - instead of a large number of custom operations, have one - ask - which will take an HttpContext -> 'a function and apply ctx to it. Effectively a bastardized version of reader. Then you can move your get_int etc. into a proper module.
According to MSDN
Upcasting is applied automatically when you pass arguments to methods
on an object type. However, for let-bound functions in a module,
upcasting is not automatic, unless the parameter type is declared as a
flexible type.
But
type C() =
member this.T() = ()
type D() =
inherit C()
let myfun (x: C)=
()
let d = D()
myfun d
I don't need to upcast at all.
Have a look at the F# spec where it says:
This means that F# functions whose inferred type includes an unsealed type in argument position may be passed subtypes when called, without the need for explicit upcasts. For example:
(The example showed there is almost the same as yours)
Also note that for let bound functions upcasting is automatically except in some cases, for example when the argument is composed, if your function was:
let myfun (x: C option)=
()
upcast is no longer automatically.
Sorry for the vague description, couldn't find a better way to plain it.
I'm starting with F# and like many others I'm translating my solved Euler problems to F#. I like to run my code using tests and also I like the FsUnit style. With the help of the given example I did this:
open System
open NUnit.Framework
open FsUnit
type EulerProblem() =
member this.problem1 = Seq.init 999 (fun n -> n + 1)
|> Seq.filter (fun n -> n % 3 = 0 || n % 5 = 0)
|> Seq.sum
[<TestFixture>]
type ``Given an Euler problem`` () =
let euler = new EulerProblem()
[<Test>] member test.
``when I try to solve #1 should return [the magic number]`` ()=
euler.problem1 |> should equal [the magic number]
This works, but I cannot understand what the period after the test method does. If I take it away the compiler complaints saying:
This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args)
Sorry if this is trivial, and maybe i'm not using the correct wording but couldn't get an answer with google.
Thanks
If you are familiar with C#, or Java, or C++, you can refer to a class instance using the this reserved word within instance members. In F#, you must explicitly give a name to the class instance for each member definition and in the FsUnit example, the name given is merely test but it's not actually used. You could just the same have written the test method as
[<Test>] member this.
``when I try to solve #1 should return [the magic number]`` ()=
euler.problem1 |> should equal [the magic number]
But note that these days, both xUnit.net and NUnit allow applying their [<Fact>] and [<Test>] attributes respectively for marking tests on let bound functions within modules and without needing TestFixtures and such, which is much better suited for F#. So, for example, the test you gave can and in my opinion ought to be written as:
module EulerProblemTests () =
[<Test>]
let ``when I try to solve #1 should return [the magic number]`` () =
let euler = new EulerProblem()
euler.problem1 |> should equal [the magic number]
Moreover, you probably don't want to create your problem solutions as members of a type like EulerProblem, rather as functions within a module.
It's still a Class, so each member has to be static, or have a "this" defined.
In your test "test" is the "this" for the member.
Normally the class would look like this:
type ClassName() =
member thisname.MethodName() =
DoSomeStuff |> DoMoreStuff
With the period, the word "test" was being used, without it it doesn't know what kind of member it is.