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.
Related
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? :-)
For the background: It's a variation on functional DI. Following Scott's post I wrote an interpreter. The twist is that my interpreter is generic and parametrized based on what you feed to it.
For testing purposes I'd like to pass another interpreter in, and therein lies the rub - how can I? Here's the simplified outline of the problem:
let y f =
let a = f 1
let b = f 2L
(a,b)
f is my generic interpreter, but here it is obviously constrained by the first use to int -> 'a.
In this simplified scenario I could just pass the interpreter twice, but in my actual implementation the type space is rather large (base type x3 output types).
Is there some F# mechanism that would let me do that, w/o too much overhead?
You can't do this in F# with functions. Functions lose genericity when passed as values.
However, F# does have a mechanism for doing it anyway, albeit a bit awkwardly: interfaces. Interface methods can be generic, so you can use them to wrap your generic functions:
type Wrapper =
abstract member f<'a> : 'a -> 'a
let y (w: Wrapper) =
let a = w.f 1
let b = w.f 2L
(a, b)
let genericFn x = x
// Calling y:
y { new Wrapper with member __.f x = genericFn x }
The downside is, you can't go back to higher-order functions, lest you lose genericity. You have to have interfaces all the way down to the turtles. For example, you can't simplify the instance creation by abstracting it as a function:
let mkWrapper f =
// no can do: `f` will be constrained to a non-generic type at this point
{ new Wrapper with member __.f x = f x }
But you can provide some convenience on the other side. At least get rid of type annotations:
type Wrapper = abstract member f<'a> (x: 'a): 'a
let callF (w: Wrapper) x = w.f x
let y w =
let a = callF w 1
let b = callF w 2L
(a,b)
(NOTE: there may be minor syntactic mistakes in the above code, as I'm writing on my phone)
Not sure if you're still interested, since you already accepted an answer, but as #Fyodorsoikin requested it, here's the 'static' way, it all happens at compile time, so no runtime overhead:
let inline y f =
let a = f $ 1
let b = f $ 2L
(a, b)
type Double = Double with static member inline ($) (Double, x) = x + x
type Triple = Triple with static member inline ($) (Triple, x) = x + x + x
type ToList = ToList with static member ($) (ToList, x) = [x]
let res1 = y Double
let res2 = y Triple
let res3 = y ToList
I use this technique when I need a generic function over arbitrary structures, I use to name the types with a single method 'Invokable'.
UPDATE
To add parameters to the function you add it to the DU, like this:
type Print<'a> = Print of 'a with
static member inline ($) (Print printer, x) = printer (string x)
let stdout (x:string) = System.Console.WriteLine x
let stderr (x:string) = System.Console.Error.WriteLine x
let res4 = y (Print stdout)
let res5 = y (Print stderr)
This is just a quick and simple sample code but this approach can be refined: you can use a method name instead of an operator, you can avoid having to repeat the DU in the declaration, and you can compose Invokables. If you are interested in these enhancements, let me know. I used a refinement of this approach before in production code and never had any issue.
Please look at Crates.
Here is a quick snippet describing the crux of what you want to accomplish. I believe this snippet is valuable in it helps teach us how we can formally reason about using F# and other ML type systems, by using mathematical language. In other words, it not only shows you how, it teaches you the deep principle of why it works.
The issue here is that we have reached a fundamental limitation of what is directly expressible in F#. It follows that the trick to simulating universal quantification is, therefore, to avoid ever passing the function around directly, instead hiding the type parameter away such that it cannot be fixed to one particular value by the caller, but how might one do that?
Recall that F# provides access to the .NET object system. What if we made our own class (in the object-oriented sense) and put a generic method on that? We could create instances of that which we could pass around, and hence carry our function with it (in the form of said method)?
// Encoding the function signature...
// val id<'a> : 'a -> 'a
// ...in terms of an interface with a single generic method
type UniversalId = abstract member Eval<'a> : 'a -> 'a
Now we can create an implementation which we can pass around without the type parameter being fixed:
// Here's the boilerplate I warned you about.
// We're implementing the "UniversalId" interface
// by providing the only reasonable implementation.
// Note how 'a isn't visible in the type of id -
// now it can't be locked down against our will!
let id : UniversalId =
{ new UniversalId with
member __.Eval<'a> (x : 'a) : 'a = x
}
Now we have a way to simulate a universally quantified function. We can pass id around as a value, and at any point we pick a type 'a to pass to it just as we would any value-level argument.
EXISTENTIAL QUANTIFICATION
There exists a type x, such that…
An existential is a value whose type is unknown statically, either because we have intentionally hidden something that was known, or because the type really is chosen at runtime, e.g. due to reflection. At runtime we can, however, inspect the existential to find the type and value inside.
If we don’t know the concrete type inside an existentially quantified type, how can we safely perform operations on it? Well, we can apply any function which itself can handle a value of any type – i.e. we can apply a universally quantified function!
In other words, existentials can be described in terms of the universals which can be used to operate upon them.
This technique is so useful that it is used in datatype generic programming library TypeShape, which allows you to scrap your boilerplate .NET reflection code, as well as MBrace and FsPickler for "packing existential data types". See Erik Tsarpalis' slides on TypeShape for more on "encoding safe existential unpacking in .NET" and encoding rank-2 types in .NET.
A reflection helper library like TypeShape also intuitively should cover most if not all your use cases: dependency injection needs to implement service location under the hood, and so TypeShape can be thought of as the "primitive combinator library" for building dependencies to inject. See the slides starting with Arbitrary Type Shapes: In particular, note the Code Lens data type:
type Lens<'T,'F> =
{
Get : 'T -> 'F
Set : 'T -> 'F -> 'T
}
Finally, for more ideas, you may care to read Don Stewart's PhD dissertation, Dynamic Extension of Typed Functional Languages.
We present a solution to the problem of dynamic extension in statically
typed functional languages with type erasure. The presented solution retains
the benefits of static checking, including type safety, aggressive optimizations, and native code compilation of components, while allowing
extensibility of programs at runtime.
Our approach is based on a framework for dynamic extension in a statically
typed setting, combining dynamic linking, runtime type checking,
first class modules and code hot swapping. We show that this framework
is sufficient to allow a broad class of dynamic extension capabilities in any
statically typed functional language with type erasure semantics.
Uniquely, we employ the full compile-time type system to perform runtime
type checking of dynamic components, and emphasize the use of native
code extension to ensure that the performance benefits of static typing
are retained in a dynamic environment. We also develop the concept of
fully dynamic software architectures, where the static core is minimal and
all code is hot swappable. Benefits of the approach include hot swappable
code and sophisticated application extension via embedded domain specific
languages.
Here are some coarse-grained design patterns Don lays out for future engineers to follow:
Section 3.6.3: Specializing Simulators Approach.
Demonstrates how to apply program specialization techniques to Monte-Carlo simulation of polymer chemistry. This approach demonstrates how you can "inject" specialized code to address so-called "peephole optimizations".
and a general chart to help frame the "tower of extensibility":
You could do that with a full fledged type:
type Function() =
member x.DoF<'a> (v:'a) = v
let y (f: Function) =
let a = f.DoF 1
let b = f.DoF 2L
(a,b)
y (Function())
I don't know a way to make it work with first class functions in F#
I don't understand how the Value Restriction in F# works. I've read the explanation in the wiki as well as the MSDN documentation. What I don't understand is:
Why, for example, this gives me a Value Restriction error (Taken from this question):
let toleq (e:float<_>) a b = (abs ( a - b ) ) < e
But ths doesn't:
let toleq e (a:float<_>) b = (abs ( a - b ) ) < e
This is generalized all right...
let is_bigger a b = a < b
but this isn't (it is specified as int):
let add a b = a + b
Why functions with implicit parameters generate Value Restriction:
this:
let item_count = List.fold (fun acc _ -> 1 + acc) 0
vs this:
let item_count l = List.fold (fun acc _ -> 1 + acc) 0 l
(Mind you, if I do use this function in a code fragment the VR error will be gone, but then the function will be specified to the type I used it for, and I want it to be generalized)
How does it work?
(I'm using the latest F#, v1.9.6.16)
EDIT
Better/recent info is here: Keeping partially applied function generic
(original below)
I think a pragmatic thing here is not to try to understand this too deeply, but rather to know a couple general strategies to get past the VR and move on with your work. It's a bit of a 'cop out' answer, but I'm not sure it makes sense to spend time understanding the intracacies of the F# type system (which continues to change in minor ways from release to release) here.
The two main strategies I would advocate are these. First, if you're defining a value with a function type (type with an arrow '->'), then ensure it is a syntactic function by doing eta-conversion:
// function that looks like a value, problem
let tupleList = List.map (fun x -> x,x)
// make it a syntactic function by adding argument to both sides
let tupleList l = List.map (fun x -> x,x) l
Second, if you still encounter VR/generalizing problems, then specify the entire type signature to say what you want (and then 'back off' as F# allows):
// below has a problem...
let toleq (e:float<_>) a b = (abs ( a - b ) ) < e
// so be fully explicit, get it working...
let toleq<[<Measure>]'u> (e:float<'u>) (a:float<'u>) (b:float<'u>) : bool =
(abs ( a - b ) ) < e
// then can experiment with removing annotations one-by-one...
let toleq<[<Measure>]'u> e (a:float<'u>) b = (abs ( a - b ) ) < e
I think those two strategies are the best pragmatic advice. That said, here's my attempt to answer your specific questions.
I don't know.
'>' is a fully generic function ('a -> 'a -> bool) which works for all types, and thus is_bigger generalizes. On the other-hand, '+' is an 'inline' function which works on a handful of primitive types and a certain class of other types; it can only be generalized inside other 'inline' functions, otherwise it must be pinned down to a specific type (or will default to 'int'). (The 'inline' method of ad-hoc polymorphism is how the mathematical operators in F# overcome the lack of "type classes".)
This is the 'syntactic function' issue I discussed above; 'let's compile down into fields/properties which, unlike functions, cannot be generic. So if you want it to be generic, make it a function. (See also this question for another exception to this rule.)
Value restriction was introduced to address some issues with polymorphism in the presence of side effects. F# inherits this from OCaml, and I believe value restriction exists in all ML variants. Here's a few more links for you to read, besides the links you cited. Since Haskell is pure, it's not subjected to this restriction.
As for your questions, I think question 3 is truly related to value restriction, while the first two are not.
No one, including the people on the F# team, knows the answer to this question in any meaningful way.
The F# type inference system is exactly like VB6 grammar in the sense that the compiler defines the truth.
Unfortunate, but true.
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
The inline keyword in F# seems to me to have a somewhat different purpose than what I'm used to in e.g. C. For example, it seems to affect a function's type (what are "statically resolved type parameters"? Aren't all F# types resolved statically?)
When should I be using inline functions?
The inline keyword indicates that a function definition should be inserted inline into any code which uses it. Most of the time, this will not have any effect on the type of the function. However, in rare cases, it can lead to a function which has a more general type, since there are constraints which cannot be expressed in the compiled form of the code in .NET, but which can be enforced when the function is being inlined.
The primary case where this applies is the use of operators.
let add a b = a + b
will have a monomorphic inferred type (probably int -> int -> int, but it could be something like float -> float -> float if you have code which uses this function at that type instead). However, by marking this function inline, the F# compiler will infer a polymorphic type:
let inline add a b = a + b
// add has type ^a -> ^b -> ^c when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
There is no way to encode this type constraint in a first class way in compiled code on .NET. However, the F# compiler can enforce this constraint at the site where it inlines the function, so that all operator uses are resolved at compile time.
The type parameters ^a, ^b, and ^c are "statically resolved type parameters", which means that the types of the arguments must be statically known at the site where those parameters are being used. This is in contrast to normal type parameters (e.g. 'a, 'b, etc.), where the parameters mean something like "some type which will be supplied later, but which can be anything".
You should use inline when you need to define a function that must have its type (re)evaluated at the site of each usage, as opposed to a normal function, which will have its type evaluated (inferred) only at the site of first usage, and then be regarded as being statically typed with that first inferred type signature everywhere else thereafter.
In the inline case, the function definition is effectively generic/ polymorphic, whereas in the normal (none-inline) case, the function is statically (and often implicitly) typed.
So, if you use inline, the following code:
let inline add a b = a + b
[<EntryPoint>]
let main args =
let one = 1
let two = 2
let three = add one two
// here add has been compiled to take 2 ints and return an int
let dog = "dog"
let cat = "cat"
let dogcat = add dog cat
// here add has been compiled to take 2 strings and return a string
printfn "%i" three
printfn "%s" dogcat
0
will compile, build and run to produce the following output:
3
dogcat
In other words, the same add function definition has been used to produce both a function that adds two integers, and a function that concatenates two strings (in fact the underlying operator overloading on + is also achieved under the hood using inline).
Whereas this code, identical except that the add function is no longer declared inline:
let add a b = a + b
[<EntryPoint>]
let main args =
let one = 1
let two = 2
let three = add one two
// here add has been compiled to take 2 ints and return an int
let dog = "dog"
let cat = "cat"
let dogcat = add dog cat
// since add was not declared inline, it cannot be recompiled
// and so we now have a type mismatch here
printfn "%i" three
printfn "%s" dogcat
0
will NOT compile, failing with this complaint:
let dogcat = add dog cat
^^^ - This expression was expected to have type int
but instead has type string
A good example of where using inline is appropriate, is when you want to define a high order function (HOF, i.e. a function taking (other) functions as arguments), e.g. a generic function to reverse the order of the application of arguments of a function with 2 arguments, e.g.
let inline flip f x y = f y x
as is done in the answer from #pad to this question Different argument order for getting N-th element of Array, List or Seq.
When should I be using inline functions?
The most valuable application of the inline keyword in practice is inlining higher-order functions to the call site where their function arguments are also inlined in order to produce a singly fully-optimized piece of code.
For example, the inline in the following fold function makes it 5× faster:
let inline fold f a (xs: _ []) =
let mutable a = a
for i=0 to xs.Length-1 do
a <- f a xs.[i]
a
Note that this bears little resemblance to what inline does in most other languages. You can achieve a similar effect using template metaprogramming in C++ but F# can also inline between compiled assemblies because inline is conveyed via .NET metadata.
The F# component design guidelines only mention a little about this. My recommendation (that aligns well with what's said there) is:
Don't use inline
Exception: you might consider using inline when writing mathematical libraries to be consumed by other F# code and you want to write functions that are generic over different numeric data types.
There are lots of other "interesting" uses of inline and static member constraints for "duck-typing" kinds of scenarios that work a bit like C++ templates. My advice is to avoid all of that like the plague.
#kvb's answer goes into more depth about what 'static type constraints' are.