F# strange difference in resolving class method calls - f#

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.

Related

Understanding F# value restriction

I'm learning F#. I'm here because I had something hard to understand about value restriction.
Here are the examples from the book I'm studying with.
let mapFirst = List.map fst
Since I had learned FP with haskell, I was pretty sure that this code would be well compiled, but it was not the case. It resulted error FS0030 (Sorry that I can't copy-paste fsi error message, since it was written in korean). Instead, I had to provide an explicit argument like:
let mapFirst inp = List.map fst inp // or inp |> List.map fst
But why? I thought that with the above example, compiler can surely infer the type of given value:
val mapFirst : ('a * 'b) list -> 'a list
If I remind correctly, I called this thing in haskell eta-conversion, and above two examples are entirely identical. (Maybe not entirely, though). Why should I privide parameters explicitly to the function can be curried without any loss of information?
I've understood that something like
let empties = Array.create 100 []
will not compile and why, but I don't think It has something to do with my question.
※ I took a look on this question, but it did not help.
This has to do with mutability.
Consider this snippet:
type T<'a> = { mutable x : 'a option }
let t = { x = None }
The type of t is T<'a> - that is, t is generic, it has a generic parameter 'a, meaning t.x can be of any type - whatever the consumer chooses.
Then, suppose in one part of the program you do:
t.x <- Some 42
Perfectly legitimate: when accessing t you choose 'a = int and then t.x : int option, so you can push Some 42 into it.
Then, suppose in another part of your program you do:
t.x <- Some "foo"
Oh noes, what happens now? Is t.x : int option or is it string option? If the compiler faithfully compiled your code, it would result in data corruption. So the compiler refuses, just in case.
Since in general the compiler can't really check if there is something mutable deep inside your type, it takes the safe route and rejects values (meaning "not functions") that are inferred to be generic.
Note that this applies to syntactic values, not logical ones. Even if your value is really a function, but isn't syntactically defined as such (i.e. lacks parameters), the value restriction still applies. As an illustration, consider this:
type T<'a> = { mutable x : 'a option }
let f t x =
t.x <- Some x
let g = f { x = None }
Here, even though g is really a function, the restriction works in exactly the same as with my first example above: every call to g tries to operate on the same generic value T<'a>
In some simpler cases the compiler can take a shortcut though. Thus, for example this line alone doesn't compile:
let f = List.map id
But these two lines do:
let f = List.map id
let x = f [1;2;3]
This is because the second line allows the compiler to infer that f : list int -> list int, so the generic parameter disappears, and everybody is happy.
In practice it turns out that this shortcut covers the vast majority of cases. The only time you really bump against the value restriction is when you try to export such generic value from the module.
In Haskell this whole situation doesn't happen, because Haskell doesn't admit mutation. Simple as that.
But then again, even though Haskell doesn't admit mutation, it kinda sorta does - via unsafePerformIO. And guess what - in that scenario you do risk bumping into the same problem. It's even mentioned in the documentation.
Except GHC doesn't refuse to compile it - after all, if you're using unsafePerformIO, you must know what you're doing. Right? :-)

Using functions before they are declared

For the sake of using literate programming (i.e. cweb) in F#, I need to be able to forward declare functions (i.e. use them before defining them). I came up with two ways, both of them unpleasing. Can you think of something better (easier to use for the programmer)?
Nice, but doesn't work with polymorphic functions
// This can be ugly
let declare<'a> = ref Unchecked.defaultof<'a>
// This has to be beautiful
let add = declare<float -> float>
let ``function I want to explain that depends on add`` nums = nums |> Seq.map !add
add := fun x -> x + 1.
Ugly, but works with everything
// This can be ugly
type Literate() =
static member Declare<'a, 'b> (ref : obj ref) (x : 'a) : 'b =
unbox <| (unbox<obj -> obj> !ref)
static member Define<'a, 'b> (func : 'a -> 'b) (ref : obj ref) (f : 'a -> 'b) =
ref := box (unbox<'a> >> f >> box)
// This has to be beautiful
let rec id (x : 'a) : 'a = Literate.Declare idImpl x
and idImpl = ref null
let f () = id 100 + id 200
Literate.Define id idImpl (fun x -> x)
I used a tool that follows the same ideas as literate programming when creating www.tryjoinads.org. A document is simply a Markdown with code snippets that get turned into an F# source code that you can run and the snippets have to be in a correct order. (In some literate programming tools, the documentation is written in commments, but the idea is the same.)
Now, I think that making your code more complicated so that you can write it in a literate programming style (and document it) is introducing a lot of accidental complexity and it is defeating the main purpose of literate programming.
So, if I wanted to solve this problem, I would extend my literate programming tool with some annotation that specifies the order of code blocks that is needed to make the script work (and a simple pre-processing tool can re-order them when generating F# input). You can take a [look at my build script][1] for TryJoinads, which would be fairly easy to extend to do this.
The tool I used for TryJoinads already provides some meta-tags that can be used to hide code blocks from the output, so you can write something like:
## This is my page heading
[hide]
// This function will be hidden from the generated HTML
// but it is visible to the F# compiler
let add a b = a + b
Here is the description for the other function:
let functionThatUsesAdd x = add x x
And later on I can repeat `add` with more comments (and I can add an annotation
`module` to avoid conflicts with the previous declaration):
[module=Demo]
let add a b =
// Add a and b
a + b
This also isn't perfect, because you have to duplicate functions, but at least your generated blog post or HTML documentation will not be obscured by things that do not matter. But of course, adding some meta-command like module or hide to specify order of blocks wouldn't be too hard and it would be a clean solution.
In summary, I think you just need a better literate programming tool, not different F# code or F# langauge.
Perhaps I'm missing something, but why aren't you going all the way and 'doing it properly'?
Using the function first:
<<test.fs>>=
<<add>>
let inc = add 1
Declaring the function afterwards:
<<add>>=
let add a b = a + b
Since functions are first-class objects in F#, you can pass them around instead -- which presents a much nicer (and still immutable) solution than forward references.
let dependentFunction f nums = nums |> Seq.map f
let ``function I want to explain that depends on add`` nums =
dependentFunction (fun x -> x + 1.) nums
Also, in most cases you should be able to use currying (partial function application) to simplify the code further but the type inference for seq<'T> is a little strange in F# because it's usually used as a flexible type (similar to covariance in C# 4.0). To illustrate:
// This doesn't work because of type inference on seq<'T>,
// but it should work with most other types.
let ``function I want to explain that depends on add`` =
dependentFunction (fun x -> x + 1.)
Finally, a good rule of thumb for using ref or mutable in F# is that if you're only going to assign the value once (to initialize it), there's probably a cleaner, more functional way to write that code (passing the value as a function parameter (as above) and lazy are two such approaches). Obviously there are exceptions to this rule, but even then they should be used very sparingly.
As I said, this is wrong (and you should publish a blog article, or a FPish post, about why you're doing this)), but here is my take:
let ``function I want to explain that depends on add``
(add : float -> float) = nums |> Seq.map add
let add = (+) 1.
let ``function I want to explain that depends on add`` = ``function I want to explain that depends on add`` add

Optionally taking the first item in a sequence

I need a function like Seq.head, but returning None instead of throwing an exception when the sequence is empty, i.e., seq<'T> -> 'T option.
There are a jillion ways to do this. Here are several:
let items = Seq.init 10 id
let a = Seq.tryFind (fun _ -> true) items
let b = Seq.tryPick Some items
let c = if Seq.isEmpty items then None else Some (Seq.head items)
let d =
use e = items.GetEnumerator()
if e.MoveNext() then Some e.Current
else None
b is the one I use. Two questions:
Is there a particularly idiomatic way to do this?
Since there's no built-in Seq.tryHead function, does that indicate this shouldn't be necessary, is uncommon, or is better implemented without a function?
UPDATE
tryHead has been added to the standard library in F# 4.0.
I think (b) is probably the most idiomatic, for the same reason #Ramon gave.
I think the lack of Seq.tryHead just means that it is not super common.
I'm not sure, but my guess is that functional languages with Hindley-Milner type inference in general are sparse about implementing such specific functions on collection types because overloading isn't available and composing higher-order functions can be done tersely.
For example, C# Linq extensions are much more exhaustive than functions in F#'s Seq module (which itself is more exhaustive than functions on concrete collection types), and even has IEnumerable.FirstOrDefault. Practically every overload has a variation which performs a map.
I think emphasis on pattern matching and concrete types like list is also a reason.
Now, most of the above is speculation, but I think I may have a notion closer to being objective. I think a lot of the time tryPick and tryFind can be used in the first place instead of filter |> tryHead. For example, I find myself writing code like the following fairly frequently:
open System.Reflection
let ty = typeof<System.String> //suppose this type is actually unknown at compile time
seq {
for name in ["a";"b";"c"] do
yield ty.GetMethod(name)
} |> Seq.tryFind((<>)null)
instead of like
...
seq {
for name in ["a";"b";"c"] do
match ty.GetMethod(name) with
| null -> ()
| mi -> yield mi
} |> tryHead
You could define:
let seqTryHead s = Seq.tryPick Some s
It is of type seq<'a> -> 'a option. Note that I don't beta-reduce because of the generic value limitation.

What the period (.) does in a F# method

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.

How to have two methods calling each other?

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.

Resources