I'm working with a library (WPF extended toolkit) where almost every property is a Nullable<'T>. This makes it something of a pain everywhere to constantly have to write
checkbox.IsChecked <- new Nullable<bool>(true)
In C# this would convert implicitly. Is there any way to mimic the same behavior in F#? The most succinct option I've found is
checkbox.IsChecked <- unbox true
but that seems to generate more overhead in a tight loop (micro-optimization, but still), and even still it's less succinct than C#.
The new keyword is optional, and type inference will take care of the generic argument:
open System
checkbox.IsChecked <- Nullable true
If you prefer not to type ten extra keystrokes each time, you can declare a function as Carsten König described, but the declaration need not be as verbose as his:
let nl x = Nullable x
checkbox.IsChecked <- nl true
have a look at this question: Nullablle<>'s and "null" in F# - you can do the same to wrap any value in a generic way:
let nl (x : 'a) =
System.Nullable<'a> (x)
and just use it like this:
checkbox.IsChecked <- nl true;
One fix is to define a prefix operator:
let inline (!) (x: ^a) = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)
checkbox.IsChecked <- !true
Be aware that this shadows the de-referencing operator. If that's an issue you can pick a different symbol.
Related
Why do I have to tell F# whether I am using a int or float in this line
let total counts = Array.sum counts to let total (counts:int[]) = Array.sum counts ?
Coming from sml I am finding F# type inference a bit too restrictive.
P.S. I don't know much about the landscape of functional languages but would be interested if someone could enlighten me which F-languages are used out in the wild.
In F# compilation is single pass and (mostly) strictly feed-forward. I believe this is done to improve compile times but I'm not sure. The result is that in the expression Array.sum counts the sum function doesn't know what type counts is unless you add a type annotation.
You can write the computationally equivalent expression counts |> Array.sum and because counts appears earlier in the file sum is able to resolve the type correctly. This is one of the reasons the pipeline operator |> is so common in F# code.
(The rec and and keywords allows the compiler to to refer to things forward in the source file to permit mutually recursive functions and types and members within class definitions are mutually recursive by default but this is the exception.)
Not a direct answer but you have the option of creating an inline function which will be more generic:
let inline total counts = Array.sum counts
The type of this automatically gets inferred with the necessary statically resolved type parameters:
> val inline total:
counts: ^a[] -> ^a
when ^a: (static member (+) : ^a * ^a -> ^a) and
^a: (static member get_Zero: -> ^a)
Usage:
total [|1; 2; 3|] // 6
total [|1.; 2.; 3.|] // 6.0
According to the error message I get the problem is that you have to constrain it to a type that support the '+' operator.
I assume that both float and int does that but not the default type 'obj' which is the type you get if you don't specify the type of the array.
I thought that conversions between F# functions and System.Func had to be done manually, but there appears to be a case where the compiler (sometimes) does it for you. And when it goes wrong the error message isn't accurate:
module Foo =
let dict = new System.Collections.Generic.Dictionary<string, System.Func<obj,obj>>()
let f (x:obj) = x
do
// Question 1: why does this compile without explicit type conversion?
dict.["foo"] <- fun (x:obj) -> x
// Question 2: given that the above line compiles, why does this fail?
dict.["bar"] <- f
The last line fails to compile, and the error is:
This expression was expected to have type
System.Func<obj,obj>
but here has type
'a -> obj
Clearly the function f doesn't have a signature of 'a > obj. If the F# 3.1 compiler is happy with the first dictionary assignment, then why not the second?
The part of the spec that should explain this is 8.13.7 Type Directed Conversions at Member Invocations. In short, when invoking a member, an automatic conversion from an F# function to a delegate will be applied. Unfortunately, the spec is a bit unclear; from the wording it seems that this conversion might apply to any function expression, but in practice it only appears to apply to anonymous function expressions.
The spec is also a bit out of date; in F# 3.0 type directed conversions also enable a conversion to a System.Linq.Expressions.Expression<SomeDelegateType>.
EDIT
In looking at some past correspondence with the F# team, I think I've tracked down how a conversion could get applied to a non-syntactic function expression. I'll include it here for completeness, but it's a bit of a strange corner case, so for most purposes you should probably consider the rule to be that only syntactic functions will have the type directed conversion applied.
The exception is that overload resolution can result in converting an arbitrary expression of function type; this is partly explained by section 14.4 Method Application Resolution, although it's pretty dense and still not entirely clear. Basically, the argument expressions are only elaborated when there are multiple overloads; when there's just a single candidate method, the argument types are asserted against the unelaborated arguments (note: it's not obvious that this should actually matter in terms of whether the conversion is applicable, but it does matter empirically). Here's an example demonstrating this exception:
type T =
static member M(i:int) = "first overload"
static member M(f:System.Func<int,int>) = "second overload"
let f i = i + 1
T.M f |> printfn "%s"
EDIT: This answer explains only the mysterious promotion to 'a -> obj. #kvb points out that replacing obj with int in OPs example still doesn't work, so that promotion is in itself insufficient explanation for the observed behaviour.
To increase flexibility, the F# type elaborator may under certain conditions promote a named function from f : SomeType -> OtherType to f<'a where 'a :> SomeType> : 'a -> OtherType. This is to reduce the need for upcasts. (See spec. 14.4.2.)
Question 2 first:
dict["bar"] <- f (* Why does this fail? *)
Because f is a "named function", its type is promoted from f : obj -> obj following sec. 14.4.2 to the seemingly less restrictive f<'a where 'a :> obj> : 'a -> obj. But this type is incompatible with System.Func<obj, obj>.
Question 1:
dict["foo"] <- fun (x:obj) -> x (* Why doesn't this, then? *)
This is fine because the anonymous function is not named, and so sec. 14.4.2 does not apply. The type is never promoted from obj -> obj and so fits.
We can observe the interpreter exhibit behaviour following 14.4.2:
> let f = id : obj -> obj
val f : (obj -> obj) (* Ok, f has type obj -> obj *)
> f
val it : ('a -> obj) = <fun:it#135-31> (* f promoted when used. *)
(The interpreter doesn't output constraints to obj.)
As I know, explicit type parameters in value definitions is a one way to overcome "value restriction" problem.
Is there another cases when I need to use them?
Upd: I mean "explicitly generic constructs", where type parameter is enclosed in angle brackets, i.e.
let f<'T> x = x
Polymorphic recursion is another case. That is, if you want to use a different generic instantiation within the function body, then you need to use explicit parameters on the definition:
// perfectly balanced tree
type 'a PerfectTree =
| Single of 'a
| Node of ('a*'a) PerfectTree
// need type parameters here
let rec fold<'a,'b> (f:'a -> 'b) (g:'b->'b->'b) : 'a PerfectTree -> 'b = function
| Single a -> f a
| Node t -> t |> fold (fun (a,b) -> g (f a) (f b)) g
let sum = fold id (+)
let ten = sum (Node(Node(Single((1,2),(3,4)))))
This would likely be rare, but when you want to prevent further generalization (§14.6.7):
Explicit type parameter definitions on value and member definitions can affect the process of type inference and generalization. In particular, a declaration that includes explicit generic parameters will not be generalized beyond those generic parameters. For example, consider this function:
let f<'T> (x : 'T) y = x
During type inference, this will result in a function of the following type, where '_b is a type inference variable that is yet to be resolved.
f<'T> : 'T -> '_b -> '_b
To permit generalization at these definitions, either remove the explicit generic parameters (if they can be inferred), or use the required number of parameters, as the following example shows:
let throw<'T,'U> (x:'T) (y:'U) = x
Of course, you could also accomplish this with type annotations.
Most obvious example: write a function to calculate the length of a string.
You have to write:
let f (a:string) = a.Length
and you need the annotation. Without the annotation, the compiler can't determine the type of a. Other similar examples exist - particularly when using libraries designed to be used from C#.
Dealing with updated answer:
The same problem applies - string becomes A<string> which has a method get that returns a string
let f (a:A<string>) = a.get().Length
In F# why does my add function not add two floats
let add a b = a+b
(add 3 4) //returns 7
(add 3.5 5.5) //error
also please explain how type inference works in F#.
Thanks.
You have to make it inline.
let inline add a b = a+b
The problem is that + is an inline operator, so if your function add is not inline it will take the default overload which is for int.
Have a look at this answer Use of `inline` in F#
When the function is declared inline, type inference will infer the static type constraints.
val inline add :
^a -> ^b -> ^c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
So now a and b could be any type that implement the static member (+) with that signature.
If you only want your function to work with floats use a type annotation.
let add (a:float) b = a + b //float -> float -> float
In F#, the type inference system just puts a type of int when you are dealing with numbers, due to technical restrictions.
In Haskell, add :: Num a => a -> a -> a works because of typeclasses, which is different from .NET classes. Typeclasses do not fit F#.
See http://en.wikibooks.org/wiki/F_Sharp_Programming/Basic_Concepts#Type_Inference and http://en.wikibooks.org/wiki/F_Sharp_Programming/Values_and_Functions
My two cents here.
Actually if you change the order of the execution to,
let add a b = a+b
(add 3.5 5.5) //returns 9.0
(add 3 4) //error
You will see that F# does do add to two floats. ( This answers your question In F# why does my add function not add two floats )
And notice that in this snippet, F# infers the function add type as float -> float -> float.
Why F# infers function type differently in the two cases even you define the function in the exact same way?
I think that when you define the function, F# gives the type int to the function. But internally, F# remains flexible about the "true" type of the function. The first time/line you call the function, the compiler sees how you use it and thus your "intention" of the function type is understood by the compiler. And the compiler adjust the type accordingly.
Once the compiler "thinks" it gets the "true type" of the function, it is what it is. And due to that F# is statically typed, you cannot make a second call to the function with a different type of argument.
That being said, I recommend you try these snippet.
let add a b = a + b
add "str" "ing"
It should work.
let add a b = a + b
add 5. 6.
add "str" "ing" // error, check the type
Correct me if I am wrong. Hope this helps.
I've read through a good chunk of Expert F# and am working on building an actual application. While debugging, I've grown accustomed to passing fsi commands like this to make things legible in the repl window:
fsi.AddPrinter(fun (x : myType) -> myType.ToString())
I would like to extend this to work with the printf formatter, so I could type e.g.
printf "%A" instanceOfMyType
and control the output for a custom type. The book implies that this can be done (p 93, "Generic structural formatting can be extended to work with any user-defined data types,
a topic covered on the F# website"), but I have failed to find any references as to how to actually accomplish this. Does anyone know how? Is it even possible?
Edit:
I should have included a code sample, it's a record type that I'm dealing with, e.g.
type myType =
{a: int}
override m.ToString() = "hello"
let t = {a=5}
printfn "%A" t
printfn "%A" (box t)
both print statements yield:
{a = 5;}
It looks like the Right Way to do this in F# 2.0 is by using the StructuredFormatDisplay attribute, for example:
[<StructuredFormatDisplay("hello {a}")>]
type myType = {a: int}
In this example, instead of the default {a = 42;}, you would get hello 42.
This works the same way for object, record, and union types. And although the pattern must be of the format "PreText {PropertyName} PostText" (PreText and PostText being optional), this is actually more powerful than ToString() because:
PropertyName can be a property of any type. If it is not a string, then it will also be subject to structured formatting. Don Syme's blog gives an example of recursively formatting a tree in this way.
It may be a calculated property. So you could actually get ToString() to work for record and union types, though in a rather round-about way:
[<StructuredFormatDisplay("{AsString}")>]
type myType =
{a: int}
override m.ToString() = "hello"
member m.AsString = m.ToString() // a property that calls a method
By the way, ToString() will always be used (even for record and union types) if you call printfn "%O" instead of printfn "%A".
Hmm... I vaguely recall some changes to this, but I forget if they happened before or after the CTP (1.9.6.2).
In any case, on the CTP, I see that
type MyType() =
override this.ToString() = "hi"
let x = new MyType()
let xs = Array.create 25 x
printfn "%A" x
printfn "%A" xs
when evaluated in the VFSI window does what I would want, and that
x;;
xs;;
also prints nicely. So, I guess I am unclear how this differs from what is desired?
If you override ToString method, that should do.