F# Ways to help type inference? - f#

In Expert F# 2.0 by Don Syme, Adam Granicz, and Antonio Cisternino, pg. 44
Type inference: Using the |> operator lets type information flow from
input objects to the functions manipulating those objects. F# uses
information collected from type inference to resolve some language
constructs such as property accesses and method overloading. This
relies on information being propagated left to right thorough the text
of a program. In particular, type information to the right of a position
isn't taken into account when resolving property access and overload.
So clearly using |> can help type inference.
As always, declaring the type is also helpful.
Are there any other means/tactics that can be used to help F# type inference?
EDIT
As RamonSnir correctly pointed out one is supposed to let type inference do as much work as possible. So adding type declarations just because you can is not what one should do. Do not take this question or answers as something that should be done. I asked the question to help better understand the nuance of type inference and what might help in those occasions when type inference needs help. So if type inference can resolve all of the types without help, then don't give it any, but when it does, it would be nice to know some ways to help it.

A few points:
1) Prefer module functions to properties and methods.
List.map (fun x -> x.Length) ["hello"; "world"] // fails
List.map String.length ["hello"; "world"] // works
let mapFirst xss = Array.map (fun xs -> xs.[0]) xss // fails
let mapFirst xss = Array.map (fun xs -> Array.get xs 0) xss // works
2) Prefer methods without overloading. For example, QuickLinq Helpers define non-overloaded members to avoid a bunch of type annotation in LINQ extension methods.
3) Make use of any available information to give some hints to the type checker.
let makeStreamReader x = new System.IO.StreamReader(x) // fails
let makeStreamReader x = new System.IO.StreamReader(path=x) // works
The last example is taken from an excellent write-up about F# type inference.
To conclude, you don't often need to help F# type checker. If there is a type error, the summary from the link above gives a good fixing guideline:
So to summarize, the things that you can do if the compiler is
complaining about missing types, or not enough information, are:
Define things before they are used (this includes making sure the files are compiled in the right order)
Put the things that have "known types" earlier than things that have "unknown types". In particular, you might be able reorder pipes
and similar chained functions so that the typed objects come first.
Annotate as needed. One common trick is to add annotations until everything works, and then take them away one by one until you have
the minimum needed. Do try to avoid annotating if possible. Not only
is it not aesthetically pleasing, but it makes the code more brittle.
It is a lot easier to change types if there are no explicit
dependencies on them.

Related

What's the advantage of having a type to represent a function?

What's the advantage of having a type represent a function?
For example, I have observed the following snippet:
type Soldier = Soldier of PieceProperties
type King = King of PieceProperties
type Crown = Soldier -> King
Is it just to support Partial Application when additional args have yet to be satisfied?
As Fyodor Soikin says in the comments
Same reason you give names to everything else - values, functions,
modules, etc.
In other words, think about programming in assembly which typically does not use types, (yes I am aware of typed assembly) and all of the problems that one can have and then how many of those problems are solved or reduced by adding types.
So before you programmed with a language that supported functions but that used static typing, you typed everything. Now that you are using F# which has static typing and functions, just extend what you have been using typing for but now add the ability to type the functions.
To quote Benjamin C. Pierce from "Types and Programming Languages"
A type system is a tractable syntactic method for proving the absence
of certain program behaviors by classifying phrases according to the
kinds of values they compute.
As noted in "Types and Programming Languages" Section 1.2
What Type Systems Are Good For
Detecting Errors
Abstraction
Documentation
Language Safety
Efficiency
TL;DR
One of the places that I find named type function definitions invaluable is when I am building parser combinators. During the construction of the functions I fully type the functions so that I know what the types are as opposed to what type inferencing will infer they are which might be different than what I want. Since the function types typically have several parameters it is easier to just give the function type a name, and then use that name everywhere it is needed. This also saves time because the function definition is consistent and avoid having to debug an improperly declared function definition; yes I have made mistakes by doing each function type by hand and learned my lesson. Once all of the functions work, I then remove the type definitions from the functions, but leave the type definition as comments so that it makes the code easier to understand.
A side benefit of using the named type definitions is that when creating test cases, the typing rules in the named function will ensure that the data used for the test is of the correct type. This also makes understanding the data for the test much easier to understand when you come back to it after many months.
Another advantage is that using function names makes the code easier to understand because when a person new to the code looks at if for the first time they can spot the consistency of the names. Also if the names are meaningful then it makes understanding the code much easier.
You have to remember that functions are also values in F#. And you can do pretty much the same stuff with them as other types. For example you can have a function that returns other functions. Or you can have a list that stores functions. In these cases it will help if you are explicit about the function signature. The function type definition will help you to constrain on the parameters and return types. Also, you might have a complicated type signature, a type definition will make it more readable. This maybe a bit contrived but you can do fun(ky) stuff like this:
type FuncX = int -> int
type FuncZ = float -> float -> float
let addxy (x:int) :FuncX = (+) x
let subxy :FuncX = (-) x
let addz (x:float) :FuncZ =
fun (x:float) -> (fun y -> x + y)
let listofFunc = [addxy 10;addxy 20; subxy 10]
If you check the type of listofFunc you will see it's FuncX list. Also the :FuncX refers to the return type of the function. But we could you use it as an input type as well:
let compFunc (x:FuncX) (z:FuncX) =
[(x 10);(z 10)]
compFunc (addxy 10) (addxy 20)

Choose implementation at compile time in F#

Most programming languages have some way of choosing an implementation at compile-time based on types. Function overloading is a common way of doing this. Using templates (in C++ or D possibly with constraits) is another option.
But in F#, I cannot find out how to do this without using class methods, and thus loosing some nice properties like currying.
let f (a:int) =
Gives Duplicate definition of 'f'
F# has statically resolved type parameters, but I don't how I can use this..
let f (a:^T) =
match T with
Gives The value or constructor of T is not defined at match T
let f (a:^T) =
match a with
| :> int as i ->
Gives Unexpected symbol ':>' in expression
let f (a:^T) =
match ^a with
| :> int as i ->
Gives Unexpected infix operator in expression
If you want to write a function that behaves differently for different types and is an ordinary F# function, then static member constraints let you do that. However, if you want to write idiomatic F# code, then there are other options:
Here is a good example showing how you can use static member constraints to do this
F# collections use different module for each type, so there is Array.map, List.map, Seq.map etc. This is idiomatic style for functional F# libraries.
FSharpChart is an example of a library that uses overloaded methods. Note that you can use static methods, so you can write Chart.Line [ ... ] and it will pick the right overload.
If you want to write generic numeric code, then I recently wrote a tutorial that covers this topic.
So, I would be a bit careful before using static constraints - it is not entirely idiomatic (e.g. not commonly used in standard libraries) and so it may cause some confusion. But it is quite powerful and certainly useful.
The key is that simply following patterns that work well in other languages might not give you the best results in F#. If you can provide a concrete example of what you're trying to do, then you might get a better results.

What are the benefits of type inference?

I'm started to learn F#, and I noticed that one of the major differences in syntax from C# is that type inference is used much more than in C#. This is usually presented as one of the benefits of F#. Why is type inference presented as benefit?
Imagine, you have a class hierarchy and code that uses different classes from it. Strong typing allows you quickly detect which classes are used in any method.
With type inference it will not be so obvious and you have to use hints to understand, which class is used. Are there any techniques that exist to make F# code more readable with type inference?
This question assumes that you are using object-oriented programming (e.g. complex class hierarchies) in F#. While you can certainly do that, using OO concepts is mainly useful for interoperability or for wrapping some F# functionality in a .NET library.
Understanding code. Type inference becomes much more useful when you write code in the functional style. It makes code shorter, but also helps you understand what is going on. For example, if you write map function over list (the Select method in LINQ):
let map f list =
seq { for el in list -> f el }
The type inference tells you that the function type is:
val map : f:('a -> 'b) -> list:seq<'a> -> seq<'b>
This matches our expectations about what we wanted to write - the argument f is a function turning values of type 'a into values of type 'b and the map function takes a list of 'a values and produces a list of 'b values. So you can use the type inference to easily check that your code does what you would expect.
Generalization. Automatic generalization (mentioned in the comments) means that the above code is automatically as reusable as possible. In C#, you might write:
IEnumerable<int> Select(IEnumerable<int> list, Func<int, int> f) {
foreach(int el in list)
yield return f(el);
}
This method is not generic - it is Select that works only on collections of int values. But there is no reason why it should be restricted to int - the same code would work for any types. The type inference mechanism helps you discover such generalizations.
More checking. Finally, thanks to the inference, the F# language can more easily check more things than you could if you had to write all types explicitly. This applies to many aspects of the language, but it is best demonstrated using units of measure:
let l = 1000.0<meter>
let s = 60.0<second>
let speed = l/s
The F# compiler infers that speed has a type float<meter/second> - it understands how units of measure work and infers the type including unit information. This feature is really useful, but it would be hard to use if you had to write all units by hand (because the types get long). In general, you can use more precise types, because you do not have to (always) type them.

cost of implementing pipeline operator

I'm following a language called 'elm' which is an attempt to bring a Haskel-esque syntax and FRP to Javascript. There has been some discussion here about implementing the pipeline operator from F# but the language designer has concerns about the increased cost (I assume in increased compilation time or compiler implementation complexity) over the more standard (in other FP langs at least) reverse pipeline operator (which elm already implements). Can anyone speak to this? [Feel free to post directly to that thread as well or I will paste back the best answers if no one else does].
https://groups.google.com/forum/?fromgroups=#!topic/elm-discuss/Kt0MbDyRpO4
Thanks!
In the discussion you reference, I see Evan poses two challenges:
Show me some F# project that uses it
Find some credible F# programmer talking about why it is a good idea and what costs come with it (blog post or something).
I'd answer as follows:
The forward pipe-idiom is very common in F# programming, both for stylistic (we like it) and practical (it helps type inference) reasons. Just about any F# project you'll find will use it frequently. Certainly all of my open source projects use it (Unquote, FsEye, NL found here). No doubt you'll find the same with all of the Github located F# projects including the F# compiler source itself.
Brian, a developer on the F# compiler team at Microsoft, blogged about Pipelining in F# back in 2008, a still very interesting and relevant blog which relates F# pipes to POSIX pipes. In my own estimation, there is very little cost to implementing a pipe operator. In the F# compiler, this is certainly true in every sense (it's a one-line, inline function definition).
The pipeline operator is actually incredibly simple - here is the standard definition
let inline (|>) a b = b a
Also, the . operator discussed in the thread is the reverse pipe operator in F# (<|) which enables you to eliminate some brackets.
I don't think adding pipeline operators would have a significant impact on complexity
In addition to the excellent answers already given here, I'd like to add a couple more points.
Firstly, one of the reasons why the pipeline operator is common in F# is that it helps to circumvent a shortcoming the way type inference is currently done. Specifically, if you apply an aggregate operation with a lambda function that uses OOP to a collection type inference will typically fail. For example:
Seq.map (fun z -> z.Real) zs
This fails because F# does not yet know the type of z when it encounters the property Real so it refuses to compile this code. The idiomatic fix is to use the pipeline operator:
xs |> Seq.map (fun z -> z.Real)
This is strictly uglier (IMO) but it works.
Secondly, the F# pipe operator is nice to a point but you cannot currently get the inferred type of an intermediate result. For example:
x
|> h
|> g
|> f
If there is a type error at f then the programmer will want to know the type of the value being fed into f in case the problem was actually with h or g but this is not currently possible in Visual Studio. Ironically, this was easy in OCaml with the Tuareg mode for Emacs because you could get the inferred type of any subexpression, not just an identifier.

Hidden Features of F#

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
This is the unabashed attempt of a similar C# question.
So what are your favorite F# hidden (or not) features?
Most of the features I've used so far aren't exactly hidden but have been quite refreshing. Like how trivial it is to overload operators compared to say C# or VB.NET.
And Async<T> has helped me shave off some real ugly code.
I'm quite new to the language still so it'd be great to learn what other features are being used in the wild.
User defined numeric literals can be defined by providing a module whose name starts with NumericLiteral and which defines certain methods (FromZero, FromOne, etc.).
In particular, you can use this to provide a much more readable syntax for calling LanguagePrimitives.GenericZero and LanguagePrimitives.GenericOne:
module NumericLiteralG = begin
let inline FromZero() = LanguagePrimitives.GenericZero
let inline FromOne() = LanguagePrimitives.GenericOne
end
let inline genericFactorial n =
let rec fact n = if (n = 0G) then 1G else n * (fact (n - 1G))
fact n
let flt = genericFactorial 30.
let bigI = genericFactorial 30I
F# has a little-used feature called "signature files". You can have a big implementation file full of public types/methods/modules/functions, but then you can hide and selectively expose that functionality to the sequel of the program via a signature file. That is, a signature file acts as a kind of screen/filter that enables you to make entities "public to this file" but "private to the rest of the program".
I feel like this is a pretty killer feature on the .Net platform, because the only other/prior tool you have for this kind of encapsulation is assemblies. If you have a small component with a few related types that want to be able to see each other's internal details, but don't want those types to have all those bits public to everyone, what can you do? Well, you can do two things:
You can put that component in a separate assembly, and make the members that those types share be "internal", and make the narrow part you want everyone else to see be "public", or
You just mark the internal stuff "internal" but you leave those types in your gigantic assembly and just hope that all the other code in the assembly chooses not to call those members that were only marked 'internal' because one other type needed to see it.
In my experience, on large software projects, everyone always does #2, because #1 is a non-starter for various reasons (people don't want 50 small assemblies, they want 1 or 2 or 3 large assemblies, for other maybe-good reasons unrelated to the encapsulation point I am raising (aside: everyone mentions ILMerge but no one uses it)).
So you chose option #2. Then a year later, you finally decide to refactor out that component, and you discover that over the past year, 17 other places now call into that 'internal' method that was really only meant for that one other type to call, making it really hard to factor out that bit because now everyone depends on those implementation details. Bummer.
The point is, there is no good way to create a moderate-size intra-assembly encapsulation scope/boundary in .Net. Often times "internal" is too big and "private" is too small.
... until F#. With F# signature files, you can create an encapsulation scope of "this source code file" by marking a bunch of stuff as public within the implementation file, so all the other code in the file can see it and party on it, but then use a signature file to hide all of the details expect the narrow public interface that component exposes to the rest of the world. This is happy. Define three highly related types in one file, let them see each others implementation details, but only expose the truly public stuff to everyone else. Win!
Signature files are perhaps not the ideal feature for intra-assembly encapsulation boundaries, but they are the only such feature I know, and so I cling to them like a life raft in the ocean.
TL;DR
Complexity is the enemy. Encapsulation boundaries are a weapon against this enemy. "private" is a great weapon but sometimes too small to be applicable, and "internal" is often too weak because so much code (entire assembly and all InternalsVisibleTo's) can see internal stuff. F# offers a scope bigger than "private to a type" but smaller than "the whole assembly", and that is very useful.
I wonder what happens if you add
<appSettings>
<add key="fsharp-navigationbar-enabled" value="true" />
</appSettings>
to your devenv.exe.config file? (Use at your own risk.)
Passing --warnon:1182 to the compiler turns on warnings about unused variables; variable names that begin with underscore are immune.
Automatically-generated comparison functions for algebraic data types (based on lexicographical ordering) is a nice feature that is relatively unknown; see
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!548.entry
for an example.
Yes, F# doesn't have any 'hidden' features, but it sure does have a lot of power packed into the simple language. A less-known feature of the language, is where you can basically enable duck typing despite the fact F# is staticaly typed.
See this question
F# operator "?"
for info on the question-mark operator and how it provides the basic language mechanism to build a feature akin to 'dynamic' in C#.
Not really hidden, but as a non-ML person this escaped me for quite a while:
Pattern matching can decompose arbitrarily deep into data structures.
Here's a [incredibly arbitrary] nested tuple example; this works on lists or unions or any combinations of nested values:
let listEven =
"Manipulating strings can be intriguing using F#".Split ' '
|> List.ofArray
|> List.map (fun x -> (x.Length % 2 = 0, x.Contains "i"), x)
|> List.choose
( function (true, true), s -> Some s
| _, "F#" -> Some "language"
| _ -> None )
Use of F# as a utility scripting language may be under appreciated. F# enthusiasts tend to be quants. Sometimes you want something to back up your MP3s (or dozens of database servers) that's a little more robust than batch. I've been hunting for a modern replacement for jscript / vbscript. Lately, I've used IronPython, but F# may be more complete and the .NET interaction is less cumbersome.
I like curried functions for entertainment value. Show a curried function to a pure procedural / OOP program for at least three WTFs. Starting with this is a bad way to get F# converts, though :)
Inlined operators on generic types can have different generic constraints:
type 'a Wrapper = Wrapper of 'a with
static member inline (+)(Wrapper(a),Wrapper(b)) = Wrapper(a + b)
static member inline Exp(Wrapper(a)) = Wrapper(exp a)
let objWrapper = Wrapper(obj())
let intWrapper = (Wrapper 1) + (Wrapper 2)
let fltWrapper = exp (Wrapper 1.0)
(* won''t compile *)
let _ = exp (Wrapper 1)
There are no hidden features, because F# is in design mode. All what we have is a Technical Preview, which changes every two month.
see http://research.microsoft.com/fsharp/

Resources