The following code is from chapter 5 of "F# 4.0 Design Patterns".
let a = 1,"car"
type System.Tuple<'T1,'T2> with
member t.AsString() =
sprintf "[[%A]:[%A]]" t.Item1 t.Item2
(a |> box :?> System.Tuple<int,string>).AsString()
The desired output is [[1]:["car"]]
However, a red squiggly appears under AsString(). "The field, constructor or member 'AsString' is not defined. Maybe you want one of the following: ToString"
This is a bit odd code sample - I suspect the point that this is making is that F# tuples are actually .NET tuples represented using System.Tuple - by showing that an extension to System.Tuple can be invoked on ordinary F# tuples.
I suspect the behaviour of F# has changed and it no longer allows this - it may have been that adding extensions was allowed on System.Tuple, but not on ordinary F# tuples, but the two have became more unified in the compiler.
However, you can do a very similar thing using the .NET-style extension methods:
let a = 1,"car"
[<System.Runtime.CompilerServices.ExtensionAttribute>]
type TupleExtensions =
[<System.Runtime.CompilerServices.ExtensionAttribute>]
static member AsString(t:System.Tuple<'T1,'T2>) =
sprintf "[[%A]:[%A]]" t.Item1 t.Item2
let st = (a |> box :?> System.Tuple<int,string>)
st.AsString()
This can actually be also invoked directly on an F# tuple value:
("car", 32).AsString()
Related
this is a basic question but i could not find the simple answer reading the tutorial
suppose i have this simple frame
type Person =
{ Name:string; Age:int; Countries:string list; }
let peopleRecds =
[ { Name = "Joe"; Age = 51; Countries = [ "UK"; "US"; "UK"] }
{ Name = "Tomas"; Age = 28; Countries = [ "CZ"; "UK"; "US"; "CZ" ] }
{ Name = "Eve"; Age = 2; Countries = [ "FR" ] }
{ Name = "Suzanne"; Age = 15; Countries = [ "US" ] } ]
// Turn the list of records into data frame
let peopleList = Frame.ofRecords peopleRecds
// Use the 'Name' column as a key (of type string)
let people = peopleList |> Frame.indexRowsString "Name"
How do i access the value the row for Joe ? (as a record, tuple or whatever format)
i tried this
getRow "Joe" people;;
Stopped due to error System.Exception: Operation could not be
completed due to earlier error Value restriction. The value 'it' has
been inferred to have generic type
val it : Series Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do
not intend for it to be generic, add a type annotation. at 3,0
EDIT: thanks for the answer, still i would like to know why my syntax is incorrect because i think i respected the signature
val it :
('a -> Frame<'a,'b> -> Series<'b,'c>) when 'a : equality and 'b : equality
I'll answer the second half of your question, why you got a "value restriction" error. If you search for [f#] value restriction on Stack Overflow you'll find lots of answers, which may or may not confuse you. But the really short version is: F# is built on top of the .Net framework, and .Net imposes certain limitations. Specifically, functions are allowed to be generic, but values cannot be generic. So you can do this:
let f<'TData> (a:'TData) = printfn "%A" a
but you cannot do this:
let (a:'TData) = Unchecked.defaultof<'TData>
The function definition is fine, because the underlying .Net framework knows how to handle generic functions. But you're not allowed to have generic values in .Net; any value must be a specific type.
(Note: I wrote the <'TData> in the f definition explicitly, but I didn't have to: I could have just written let f (a:'TData) = printfn "%A" a and the genericness of f would have still been understood. I could even have just written let f a = printfn "%A" a, and it would have done the same thing).
Now let's look at the error you got: "the value "it" has been inferred to have generic type val it : Series<string,obj>". If you look at the function signature of getRow that you posted, it looks like this:
('a -> Frame<'a,'b> -> Series<'b,'c>)
When you called it as getRow "Joe" people, the F# compiler was able to infer that the type 'a was string (because the parameter "Joe" is a string). And because the second argument people is a Frame<string,string>, the F# compiler was able to infer that the type 'b was also string. But the result of that function call is a Series<'b,'c>, and so far the F# compiler doesn't know anything about what 'c will be. And since you ran getRow "Joe" people at the F# interactive REPL, it tried to store the result of what you typed as the value of the name it (the F# interactive REPL always provides the value of the previous expression as it) -- but since the only type it knew so far was Series<string,'c>, F# couldn't figure out what specific type to assign to the value it. I know from looking at your code that the type 'c was the Person record, but the F# compiler couldn't know that from just that one call to getRow, because of how the getRow function is typed.
There are two ways you could have solved this value restriction error:
One way to solve this would have been to pipe the result of getRow into another function, which would have allowed the F# compiler to infer the specific type of its result. Unfortunately, since I don't know Deedle that well, I can't give you a good example here. Maybe someone else will come up with one and comment on this answer, and I'll edit it in. It would look like:
getRow "Joe" people |> (some Deedle function)
But I don't know which Deedle function to use in my example: it would have to be a function that takes a Series and does some specific calculation with it, in a way that would allow F# to infer that this is a Series<string,Person>. Sorry this isn't a great example, but I'll leave it in anyway in case it helps.
The second way you could have solved the error would have been to specify the type of the value you were getting. In F#, you do that with the : (type) syntax, e.g.:
getRow "Joe" people : Series<string,Person>
Or, since the F# compiler has enough information to infer the string part of that type, you could also have written:
getRow "Joe" people : Series<_,Person>
When you write _ in a type signature, you're telling the F# compiler "You figure out what type this is". This only works when the F# compiler has enough information to infer that type correctly, but it's often a handy shorthand when type signatures would be large and unwieldy.
Both of these approaches would have solved your immediate problem, gotten rid of the "value restriction" error, and allowed you to continue working.
I hope this answer helps you. If it hopelessly confuses you instead, let me know and I'll see if I can explain whatever has you confused.
EDIT: In the comments, Soldalma asks whether the F# compiler (which is a one-pass compiler that works top to bottom and left to right) can infer the type from a forward pipe. The answer is yes, because the expression isn't finished yet. As long as an expression isn't finished, F#'s type inference (which is based on the Hindley-Milner type system*) is fine with carrying around a set of not-yet-resolved types. And if the types are resolved before the expression is complete, then the expression can resolve to a specific value (or a specific function). If the types are not yet resolved when the expression is complete, then it has to resolve to a generic value or function. And generic functions are allowed in .Net, but not generic values, hence the "value restriction" error.
To see this in practice, let's look at some example code. Copy and paste the following code into an F# editor that lets you hover over a variable (or function) name to see its type. I recommend VS Code with the Ionide-fsharp extension since it's cross-platform, but Visual Studio will work just as well.
open System.Collections.Generic
let mkDict (key:'K) = new Dictionary<'K,'V>() // Legal
let getValueOrDefault (key:'a) (defaultVal:'b) (dict:Dictionary<'a,'b>) =
match dict.TryGetValue key with
| true,v -> v
| false,_ -> defaultVal
let d = mkDict "foo" // Error: value restriction
let bar = mkDict "foo" |> getValueOrDefault "foo" "bar" // Legal: type string
let five = mkDict "foo" |> getValueOrDefault "foo" 5 // Legal: type int
Go ahead and hover your cursor over each function and variable name to see its type, or else hit Alt+Enter to send each function or variable declaration to F# Interactive. (And once you've seen that the let d line gives a "value restriction" error, comment it out so the rest of the code will compile).
What's happening here is a good demonstration of how this all works. The mkDict function has two unresolved types, 'K and 'V, so it has to be generic. But that's fine, because .Net has no problem with generic functions. (mkDict isn't actually very useful, since it actually "throws away" the data of its argument and does nothing to it. But it's supposed to be a trivial example, so just ignore the fact that it's kind of useless.) Likewise, getValueOrDefault has two unresolved types, 'a and 'b, so it's also a generic function.
However, let d = mkDict "foo" is not legal. Here, the generic type 'K has been resolved to be the specific type string, but 'V has not yet been resolved by the time the expression is complete so d would have to be generic (it would look like d<'V> in explicitly-generic syntax). But d is not a function (since it has no parameters), it's the name of a value, and .Net doesn't allow generic values.
But in the next two lines, the expression is not complete by the time the compiler has parsed mkDict "foo", so it doesn't yet have to "lock in" the unknown types. It can quite happily carry the unresolved type 'V into the next part of the expression. And there, the getValueOrDefault function has two specific types, string and string in the first line, and string and int in the second line. Because its 'b type corresponds to the 'V type from mkDict, therefore F# can resolve 'V in both lines. And so bar has type string, and five has type int.
* Scott Wlaschin says that it should "more accurately ... be called "Damas-Milner's Algorithm W" ". Since I haven't studied it in detail myself, I'll take his word for it -- but if you're interested in learning more, the Wikipedia link I provided is probably a halfway decent starting point.
I'll be very short, promoting my comment to an answer.
You need to use syntax reverse to the one you have tried:
people.Rows.["Joe"]
C# and F# has different implementation of the default (or optional) parameters.
In C# language when you add default value to the argument you'll not change its underlying type (I mean type of the parameter). Actually optional arguments in C# is a lightweight syntactic sugar:
class CSharpOptionalArgs
{
public static void Foo(int n = 0) {}
}
// Somewhere in the call site
CSharpOptionalArgs.Foo();
// Call to Foo() will be transformed by C# compiler
// *at compile time* to something like:
const int nArg = GetFoosDefaultArgFromTheMetadata();
CSharpOptionalArgs.Foo(nArg);
But F# implements this feature in a different way. Unlike C#, F# optional arguments resolves at callee site but not at caller site:
type FSharpOptionalArgs() =
static let defaultValue() = 42
static member public Foo(?xArg) =
// Callee site decides what value to use if caller does not specifies it
let x = defaultArg xArg (defaultValue())
printfn "x is %d" x
This implementation is absolutely reasonable and much more powerful. C# optional arguments restricted only to compile-time constants (because optional arguments stored in assemblies metadata). In F# default value could be less obvious but we can use arbitrary expression as a default value. So far so good.
F# optional arguments transformed by F# compiler to Microsoft.FSharp.Core.FSharpOption<'a> which is a reference type. This means that every call to the method with optional argument in F# will lead to additional allocation at the managed head and will lead to pressure to garbage collection.
**EDITED**
// This call will NOT lead to additional heap allocation!
FSharpOptionalArgs.Foo()
// But this one will do!
FSharpOptionalArgs.Foo(12)
I don't worry about application code, but this behavior could dramatically degrade performance for libraries. What if some library method with an optional argument will be called thousands times per second?
This implementation seems really odd to me. But maybe there is some rules that library developer should avoid using of this feature or F# team is going to change this behavior in the future version of F#?
Following unit test profs that optional arguments are reference type:
[<TestFixture>]
type FSharpOptionalArgumentTests() =
static member public Foo(?xArg) =
// Callee site decides what value to use if caller does not specifies it
let x = defaultArg xArg 42
()
[<Test>]
member public this.``Optional argument is a reference type``() =
let pi = this.GetType().GetMethod("Foo").GetParameters() |> Seq.last
// Actually every optional parameter in F# is a reference type!!
pi.ParameterType |> should not' (equal typeof<int>)
pi.ParameterType.IsValueType |> should be False
()
Because nobody in F# team is not interesting yet in compiling "simple", Option-like discriminated unions as value types, supporting pattern-matching over such unions and so on :)
Remember, tuples types are heavly used in functional languages like F# (much more than default arguments), but still implemented in CLR as refererence types - nobody cares about memory allocation and functional_languages-specific GC tweaks.
F# 4.1 has C# optional attribute compatibility. However if you are developing function that will be consumed also by F# then you should use regular syntax:
member this.M (?i : int) =
let iv = defaultArg i 12
iv + 1
F# 4.1 optional arguments documentation:
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/members/methods
Say, I have
member this.Test (x: 'a) = printfn "generic"
1
member this.Test (x: Object) = printfn "non generic"
2
If I call it in C#
var a = test.Test(3); // calls generic version
var b = test.Test((object)3); // calls non generic version
var c = test.Test<object>(3); // calls generic version
However, in F#
let d = test.Test(3); // calls non generic version
let e = test.Test<int>(3); // calls generic version
So I have to add type annotation so as to get the correct overloaded method. Is this true? If so, then why F# doesn't automatically resolve correctly given that the argument type is already inferred? (what is the order of F#'s overload resolution anyway? always favor Object than its inherited classes?)
It is a bit dangerous if a method has both overloads, one of them takes argument as Object type and the other one is generic and both return the same type. (like in this example, or Assert.AreEqual in unit testing), as then it is very much likely we get the wrong overloading without even notice (won't be any compiler error). Wouldn't it be a problem?
Update:
Could someone explain
Why F# resolves Assert.AreEqual(3, 5) as Assert.AreEqual(Object a, Object b) but not Assert.AreEqual<T>(T a, T b)
But F# resolves Array.BinarySearch([|2;3|], 2) as BinarySearch<T>(T[]array, T value) but not BinarySearch(Array array, Object value)
F# Method overload resolution not as smart as C#?
I don't think it's true. Method overloading makes type inference much more difficult. F# has reasonable trade-offs to make method overloading usable and type inference as powerful as it should be.
When you pass a value to a function/method, F# compiler automatically upcasts it to an appropriate type. This is handy in many situations but also confusing sometimes.
In your example, 3 is upcasted to obj type. Both methods are applicable but the simpler (non-generic) method is chosen.
Section 14.4 Method Application Resolution in the spec specifies overloading rules quite clearly:
1) Prefer candidates whose use does not constrain the use of a
user-introduced generic type annotation to be equal to another type.
2) Prefer candidates that do not use ParamArray conversion. If two
candidates both use ParamArray conversion with types pty1 and pty2,
and pty1 feasibly subsumes pty2, prefer the second; that is, use the
candidate that has the more precise type.
3) Prefer candidates that do not have
ImplicitlyReturnedFormalArgs.
4) Prefer candidates that do not have
ImplicitlySuppliedFormalArgs.
5) If two candidates have unnamed actual argument types ty11...ty1n and ty21...ty2n, and each ty1i either
a. feasibly subsumes ty2i, or
b. ty2i is a System.Func type and ty1i is some other delegate
type, then prefer the second candidate. That is, prefer any candidate that has the more specific actual argument types, and
consider any System.Func type to be more specific than any other
delegate type.
6) Prefer candidates that are not extension members over
candidates that are.
7) To choose between two extension members, prefer the one that
results from the most recent use of open.
8) Prefer candidates that are not generic over candidates that are
generic—that is, prefer candidates that have empty ActualArgTypes.
I think it's users' responsibility to create unambiguous overloaded methods. You can always look at inferred types to see whether you're doing them correctly. For example, a modified version of yours without ambiguity:
type T() =
member this.Test (x: 'a) = printfn "generic"; 1
member this.Test (x: System.ValueType) = printfn "non-generic"; 2
let t = T()
let d = t.Test(3) // calls non-generic version
let e = t.Test(test) // call generic version
UPDATE:
It comes down a core concept, covariance. F# doesn't support covariance on arrays, lists, functions, etc. It's generally a good thing to ensure type safety (see this example).
So it's easy to explain why Array.BinarySearch([|2;3|], 2) is resolved to BinarySearch<T>(T[] array, T value). Here is another example on function arguments where
T.Test((fun () -> 2), 2)
is resolved to
T.Test(f: unit -> 'a, v: 'a)
but not to
T.Test(f: unit -> obj, v: obj)
I thought that I might be able to do this with quotations - but I can't see how.
Should I just use a table of the functions with their names - or is their a way of doing this?
Thanks.
For more info......
I'm calling a lot of f# functions from excel and I wondered if I could write a f# function
let fs_wrapper (f_name:string) (f_params:list double) =
this bit calls fname with f_params
and then use
=fs_wrapper("my_func", 3.14, 2.71)
in the sheet rather than wrap all the functions separately.
You'll need to use standard .NET Reflection to do this. Quotations aren't going to help, because they represent function calls using standard .NET MethodInfo, so you'll need to use reflection anyway. The only benefit of quotations (compared to naive reflection) is that you can compile them, which could give you better performance (but the compilation isn't perfect).
Depending on your specific scenario (e.g. where are the functions located), you'd have to do something like:
module Functions =
let sin x = sin(x)
let sqrt y = sqrt(y)
open System.Reflection
let moduleInfo =
Assembly.GetExecutingAssembly().GetTypes()
|> Seq.find (fun t -> t.Name = "Functions")
let name = "sin"
moduleInfo.GetMethod(name).Invoke(null, [| box 3.1415 |])
Unless you need some extensibility or have a large number of functions, using a dictionary containing string as a key and function value as the value may be an easier option:
let funcs =
dict [ "sin", Functions.sin;
"sqrt", Functions.sqrt ]
funcs.[name](3.1415)
There are many methods but one way is to use Reflection, for instance:
typeof<int>.GetMethod("ToString", System.Type.EmptyTypes).Invoke(1, null)
typeof<int>.GetMethod("Parse", [|typeof<string>|]).Invoke(null, [|"112"|])
GetMethod optionally takes an array of types that define the signature, but you can skip that if your method is unambiguous.
Following up on what Thomas alluded to, have a look at Using and Abusing the F# Dynamic Lookup Operator by Matthew Podwysocki. It offers a syntactically clean way for doing dynamic lookup in F#.
This is a pretty simple question, and I just wanted to check that what I'm doing and how I'm interpreting the F# makes sense. If I have the statement
let printRandom =
x = MyApplication.getRandom()
printfn "%d" x
x
Instead of creating printRandom as a function, F# runs it once and then assigns it a value. So, now, when I call printRandom, instead of getting a new random value and printing it, I simply get whatever was returned the first time. I can get around this my defining it as such:
let printRandom() =
x = MyApplication.getRandom()
printfn "%d" x
x
Is this the proper way to draw this distinction between parameter-less functions and values? This seems less than ideal to me. Does it have consequences in currying, composition, etc?
The right way to look at this is that F# has no such thing as parameter-less functions. All functions have to take a parameter, but sometimes you don't care what it is, so you use () (the singleton value of type unit). You could also make a function like this:
let printRandom unused =
x = MyApplication.getRandom()
printfn "%d" x
x
or this:
let printRandom _ =
x = MyApplication.getRandom()
printfn "%d" x
x
But () is the default way to express that you don't use the parameter. It expresses that fact to the caller, because the type is unit -> int not 'a -> int; as well as to the reader, because the call site is printRandom () not printRandom "unused".
Currying and composition do in fact rely on the fact that all functions take one parameter and return one value.
The most common way to write calls with unit, by the way, is with a space, especially in the non .NET relatives of F# like Caml, SML and Haskell. That's because () is a singleton value, not a syntactic thing like it is in C#.
Your analysis is correct.
The first instance defines a value and not a function. I admit this caught me a few times when I started with F# as well. Coming from C# it seems very natural that an assignment expression which contains multiple statements must be a lambda and hence delay evaluated.
This is just not the case in F#. Statements can be almost arbitrarily nested (and it rocks for having locally scoped functions and values). Once you get comfortable with this you start to see it as an advantage as you can create functions and continuations which are inaccessible to the rest of the function.
The second approach is the standard way for creating a function which logically takes no arguments. I don't know the precise terminology the F# team would use for this declaration though (perhaps a function taking a single argument of type unit). So I can't really comment on how it would affect currying.
Is this the proper way to draw this
distinction between parameter-less
functions and values? This seems less
than ideal to me. Does it have
consequences in currying, composition,
etc?
Yes, what you describe is correct.
For what its worth, it has a very interesting consequence able to partially evaluate functions on declaration. Compare these two functions:
// val contains : string -> bool
let contains =
let people = set ["Juliet"; "Joe"; "Bob"; "Jack"]
fun person -> people.Contains(person)
// val contains2 : string -> bool
let contains2 person =
let people = set ["Juliet"; "Joe"; "Bob"; "Jack"]
people.Contains(person)
Both functions produce identical results, contains creates its people set on declaration and reuses it, whereas contains2 creates its people set everytime you call the function. End result: contains is slightly faster. So knowing the distinction here can help you write faster code.
Assignment bodies looking like function bodies have cought a few programmers unaware. You can make things even more interesting by having the assignment return a function:
let foo =
printfn "This runs at startup"
(fun () -> printfn "This runs every time you call foo ()")
I just wrote a blog post about it at http://blog.wezeku.com/2010/08/23/values-functions-and-a-bit-of-both/.