Related
Not at all familiar with Erlang, but am trying to interpret what this code does?
Below is my understanding about the code. Any help will be useful.
I am looking at the tutorials but the passing values are confusing in this case.
example- convert_list_to_k([{Name, {l, Weight}} | Rest]) //{1,Weight} <- This one
And how is the value returned in convert_list_to_k?
let's say for this function block
convert_list_to_k([{Name, {l, Weight}} | Rest]) ->
Converted_Object = {Name, {k, Weight / 0.45359237}},
[Converted_Object | convert_list_to_k(Rest)];
convert_list_to_k([Object | Rest]) ->
[Object | convert_list_to_k(Rest)];
convert_list_to_k([]) ->
[].
Below is the code with explanations.
-module(erlang_program).
-export([format_weight/1]).
in the above export the /1 represents it's going to receive an attribute(I don't know which attribute)
format_weight(List_of_objects) ->
Converted_List = convert_list_to_k(List_of_objects),
print_weight(Converted_List),
{Max_object, Min_object} = find_max_and_min(Converted_List),
print_max_and_min(Max_object, Min_object).
Kind of main function, which will import convert_list_to_k, print_weight(Converted_List),find_max_and_min(Converted_List) and print_max_and_min(Max_object, Min_object).
According to my understanding it's doing the following things:
Converts a list of object to some format
Prints the converted list
Find the Max and Min, and place it in Object Max and Min
Prints the Max and Min Object
I am getting confused by the way [{Name, {l, Weight}} | Rest] is passed
convert_list_to_k([{Name, {l, Weight}} | Rest]) ->
Converted_Object = {Name, {k, Weight / 0.45359237}},
[Converted_Object | convert_list_to_k(Rest)];
convert_list_to_k([Object | Rest]) ->
[Object | convert_list_to_k(Rest)];
convert_list_to_k([]) ->
[].
print_weight([{Name, {k, Weight}} | Rest]) ->
io:format("~-15w ~w c~n", [Name, Weight]),
print_weight(Rest);
print_weight([]) ->
ok.
find_max_and_min([Object | Rest]) ->
find_max_and_min(Rest, Object, Object).
find_max_and_min([{Name, {k, Weight}} | Rest],
{Max_Name, {k, Max_Weight}},
{Min_Name, {k, Min_Weight}}) ->
if
Weight > Max_Weight ->
Max_Object = {Name, {k, Weight}};
true ->
Max_Object = {Max_Name, {k, Max_Weight}}
end,
if
Weight < Min_Weight ->
Min_Object = {Name, {k, Weight}};
true ->
Min_Object = {Min_Name, {k, Min_Weight}}
end,
find_max_and_min(Rest, Max_Object, Min_Object);
find_max_and_min([], Max_Object, Min_Object) ->
{Max_Object, Min_Object}.
print_max_and_min({Max_name, {k, Max_object}}, {Min_name, {k, Min_object}}) ->
io:format("Max weight was ~w c in ~w~n", [Max_object, Max_name]),
io:format("Min weight was ~w c in ~w~n", [Min_object, Min_name]).
Don't worry that this code is a bit confusing. It is somewhat unidiomatic. We'll address that in a moment...
Before style, look at this first function, convert_list_to_k/1. It is selectively converting objects from a form marked with l to a form marked with k.
How is it selecting? It is matching on the shape and value of the first element of the list passed to it as an argument. If it receives a value with an l type value inside like {Name, {l, Weight}} then the first clause is selected and run, which converts the {l, Weight} part to a {k, Weight} value -- I assume here this is "l" for "pounds" and "k" for "kilograms".
This function is doing depth recursion which is not usually a good fit for this particular case, because Erlang (and most functional languages) have an optimization for tail recursion.
foo([Thing | Things]) ->
NewThing = change(Thing),
[NewThing | foo(Things)];
foo([]) ->
[].
This is basically what the function is doing. This means that for whatever size the list is, a new layer of the call stack has to be added because the original list in the first clause cannot be returned without remembering every intermediate value. This will not work on arbitrarily long lists without significant memory overhead and is generally not how things work.
Imagine in memory seeing this:
foo([change(Thing1) | foo([change(Thing2) | foo([change(Thing3) | ...]]])
Not very tidy. Sometimes it is the right thing to do, but not in the general case of iterating over a list.
A tail recursive version would look like this:
foo(Things) ->
foo(Things, []).
foo([Thing | Things], Accumulator) ->
NewThing = change(Thing),
foo(Things, [NewThing | Accumulator]);
foo([], Accumulator) ->
lists:reverse(Accumulator).
This version runs in constant space and is the more idiomatic form of explicit recursion.
So what about all that matching stuff? Well, let's say I wanted to print a value in kilograms every time, but some of my values are in pounds and some are in kilos. I could wrap the raw number values in a tuple and use an atom to tag the values so I know what they mean. For example, a tuple like {pounds, X} would mean I have a number, X, and it is in pounds, or a tuple {kilos, X} which would mean X is kilos. Both are still weight.
So how would my function look?
print_weight({kilos, X}) ->
io:format("Weight is ~wkgs~n", [X]);
print_weight({pounds, X}) ->
Kilos = X / 0.45359237,
io:format("Weight is ~wkgs~n", [Kilos]).
So this function works fine as long as it is passed either kind of tuple.
How about a list of these? We could do explicit recursion like above:
print_weights([{kilos, X} | Rest]) ->
ok = io:format("Weight is ~wkgs~n", [X]),
print_weights(Rest);
print_weight([{pounds, X} | Rest]) ->
Kilos = X / 0.45359237,
ok = io:format("Weight is ~wkgs~n", [Kilos]),
print_weights(Rest);
print_weights([]) ->
ok.
So this handles a list of values like above. But we don't really need to write all that, do we? We already had a function called print_weight/1, and it already knows how to do the matching. What we could do instead is more simply define print_weights/1 as a function that uses a list operation:
print_weights(List) ->
lists:foreach(fun print_weight/1, List).
See, we usually don't do explicit recursion when we can help it. The reason is that in the simple case we already have higher-order functions made to simplify simple iteration over lists. In the case where we want a side effect and don't care about the return value, like printing the weights as above, we use lists:foreach/2.
Going back to the "change" example above, if we already know that we want to perform change/1 on each value, but return the same map back intact, it makes more sense to either use a list comprehension or lists:map/2.
A list comprehension is a special syntax over a map, which can also include guards. The simple case of mapping a function over every value in a list and returning that list looks like this:
ChangedThings = [change(Thing) || Thing <- Things]
A map looks almost exactly the way lists:foreach/2 did above:
ChangedThings = lists:map(fun change/1, Things)
Now, going back to your original example... maybe we want to ensure a specific value type. So we could write a simple function that does only that:
ensure_metric({Name, {l, Pounds}}) ->
Kilos = Pounds / 0.45359237,
{Name, {k, Kilos}};
ensure_metric(Value = {_, {k, _}}) ->
Value.
That's all we need. What is happening above is that any tuple of the form {Foo, {l, Bar}} matches the first clause and gets converted by the operation in that clause and then repacked to a {Foo, {k, Baz} form, and any tuple of the form {Foo, {k, Bar}} matches the second but is passed along without being changed. We can now simply map that function over a list:
convert_list_to_k(List) ->
lists:map(fun ensure_metric/1, List).
Much easier to reason about just one function at a time!
The min/max function is a bit insane. We would not want to write an if unless we had a fully bounded mathematical case. For example:
if
X > Y -> option1();
X =:= Y -> option2();
X == Y -> option3();
X < Y -> option4()
end,
This is four tests in a single clause. Occasionally using an if makes sense for that. More often, though, you wind up with what you had above, where a simple comparison happens. In that case a case is much more expressive:
case X > Y ->
true -> do_something();
false -> something_else()
end,
BUT! Maybe what we really want in a min/max function is to just operate over guards and avoid writing some complex body logic. Here is one that operates over a simple list of numbers, a slight change would make it fit the data type you are dealing with (those tuples):
min_max([Number | Numbers]) ->
min_max(Numbers, Number, Number).
min_max([N | Ns], Min, Max) when N < Min ->
min_max(Ns, N, Max);
min_max([N | Ns], Min, Max) when N > Max ->
min_max(Ns, Min, N);
min_max([_ | Ns], Min, Max) ->
min_max(Ns, Min, Max);
min_max([], Min, Max) ->
{Min, Max}.
Not a whole lot of cheetah flips are needed in procedural logic here.
Erlang is so boringly simple and tiny as a language that once the needlessness of most procedural logic sinks in you just suddenly "get new eyes". A few related Q/As with background information may be helpful on your journey:
Erlang Recursive end loop
How does the recursive call work in this erlang function?
Explanation of lists:fold function
Function chaining in Erlang
Good Morning everyone,
I must do an exercise of Programming, but i'm stuck!
Well, the exercise requires a function that given a list not empty of integers, return the first number with maximum number of occurrences.
For example:
mode [1;2;5;1;2;3;4;5;5;4:5;5] ==> 5
mode [2;1;2;1;1;2] ==> 2
mode [-1;2;1;2;5;-1;5;5;2] ==> 2
mode [7] ==> 7
Important: the exercise must be in functional programming
My idea is:
let rec occurences_counter xs i = match xs with
|[] -> failwith "Error"
|x :: xs when x = i -> 1 + occurences_counter xs i
|x :: xs -> occurences_counter xs i;;
In this function i'm stuck:
let rec mode (l : int list) : int = match l with
|[] -> failwith "Error"
|[x] -> x
|x::y::l when occurences_counter l x >= occurences_counter l y -> x :: mode l
|x::y::l when occurences_counter l y > occurences_counter l x -> y :: mode l;;
Thanks in advance, i'm newbie in programming and in stackoverflow
Sorry for my english
one solution : calculate first a list of couples (number , occurences).
hint : use List.assoc.
Then, loop over that list of couple to find the max occurrence and then return the number.
One suggestion:
your algorithm could be simplified if you sort the list before. This has O(N log(N)) complexity. Then measure the longest sequence of identical numbers.
This is a good strategy because you delegate the hard part of the work to a well known algorithm.
It is probably not the most beautiful code, but here is with what i came up (F#). At first i transform every element to an intermediate format. This format contains the element itself, the position of it occurrence and the amount it occurred.
type T<'a> = {
Element: 'a
Position: int
Occurred: int
}
The idea is that those Records can be added. So you can first transform every element, and then add them together. So a list like
[1;3]
will be first transformed to
[{Element=1;Position=0;Occurred=1}; {Element=3;Position=1;Occurred=1}]
By adding two together you only can add those with the same "Element". The Position with the lower number from both is taken, and Occurred is just added together. So if you for example have
{Element=3;Position=1;Occurred=2} {Element=3;Position=3;Occurred=2}
the result will be
{Element=3;Position=1;Occurred=4}
The idea that i had in mind was a Monoid. But in a real Monoid you had to come up that you also could add different Elements together. By trying some stuff out i feel that the restriction of just adding the same Element where way more easier. I created a small Module with the type. Including some helper functions for creating, adding and comparing.
module Occurred =
type T<'a> = {
Element: 'a
Position: int
Occurred: int
}
let create x pos occ = {Element=x; Position=pos; Occurred=occ}
let sameElements x y = x.Element = y.Element
let add x y =
if not <| sameElements x y then failwith "Cannot add two different Occurred"
create x.Element (min x.Position y.Position) (x.Occurred + y.Occurred)
let compareOccurredPosition x y =
let occ = compare x.Occurred y.Occurred
let pos = compare x.Position y.Position
match occ,pos with
| 0,x -> x * -1
| x,_ -> x
With this setup i now wrote two additional function. One aggregate function that first turns every element into a Occurred.T, group them by x.Element (the result is a list of list). And then it uses List.reduce on the inner list to add the Occurred with the same Element together. The result is a List that Contains only a single Occurred.T for every Element with the first Position and the amount of Occurred items.
let aggregate =
List.mapi (fun i x -> Occurred.create x i 1)
>> List.groupBy (fun occ -> occ.Element)
>> List.map (fun (x,occ) -> List.reduce Occurred.add occ)
You could use that aggregate function to now implement different aggregation logic. In your case you only wanted the one with the highest Occurrences and the lowest position. I wrote another function that did that.
let firstMostOccurred =
List.sortWith (fun x y -> (Occurred.compareOccurredPosition x y) * -1) >> List.head >> (fun x -> x.Element)
One note. Occurred.compareOccurredPosition is written that it sorts everything in ascending order. I think people expecting it in this order to go to the smallest to the biggest element by default. So by default the first element would be the element with the lowest occurrence and the biggest Position. By multiplying the result of it with -1 you turn that function into a descending sorting function. The reason why i did that is that i could use List.head. I also could use List.last to get the last element, but i felt that it would be better not to go through the whole list again just to get the last element. On top of it, you didn't wanted an Occurred.T you wanted the element itself, so i unwrap the Element to get the number.
Here is everything in action
let ll = [
[1;2;5;1;2;3;4;5;5;4;5;5]
[2;1;2;1;1;2]
[-1;2;1;2;5;-1;5;5;2]
[7]
]
ll
|> List.map aggregate
|> List.map firstMostOccurred
|> List.iter (printfn "%d")
This code will now print
5
2
2
7
It has still some rough edges like
Occurred.add throws an exception if you try to add Occurred with different Elements
List.head throws an exception for empty lists
And in both cases no code is written to handle those cases or making sure an exception will not raise.
You need to process you input list while maintaining a state, that stores the number of occurrences of each number. Basically, the state can be a map, where keys are in the domain of list elements, and values are in domain of natural numbers. If you will use Map the algorithm would be of O(NlogN) complexity. You can also use associative list (i.e., a list of type ('key,'value) list) to implement map. This will lead to quadratic complexity. Another approach is to use hash table or an array of the length equal to the size of the input domain. Both will give you a linear complexity.
After you collected the statistics, (i.e., a mapping from element to the number of its occurrences) you need to go through the set of winners, and choose the one, that was first on the list.
In OCaml the solution would look like this:
open Core_kernel.Std
let mode xs : int =
List.fold xs ~init:Int.Map.empty ~f:(fun stat x ->
Map.change stat x (function
| None -> Some 1
| Some n -> Some (n+1))) |>
Map.fold ~init:Int.Map.empty ~f:(fun ~key:x ~data:n modes ->
Map.add_multi modes ~key:n ~data:x) |>
Map.max_elt |> function
| None -> invalid_arg "mode: empty list"
| Some (_,ms) -> List.find_exn xs ~f:(List.mem ms)
The algorithm is the following:
Run through input and compute frequency of each element
Run through statistics and compute spectrum (i.e., a mapping from frequency to elements).
Get the set of elements that has the highest frequency, and find an element in the input list, that is in this set.
For example, if we take sample [1;2;5;1;2;3;4;5;5;4;5;5],
stats = {1 => 2; 2 => 2; 3 => 1; 4 => 2; 5 => 5}
mods = {1 => [3]; 2 => [1;2]; 5 => [5]}
You need to install core library to play with it. Use coretop to play with this function in the toplevel. Or corebuild to compile it, like this:
corebuild test.byte --
if the source code is stored in test.ml
I want to know how to split a given list into two lists such that both lists have the same sum. I want to do that by using concurrency. I am doing this in erlang.
So, I'm doing something like this:
Read the list, if its sum is even, then proceed else fail. Take the first element of the list and check if it is greater than half of the sum, if not, then I add this element to a new list. Next, I take the second element of the list, check the sum of this element and that of the new list and do the same operation. And so on.. Such that when the sum in the new list is equal to half of the sum of the first list, it calls another function to send the remaining elements.
-module(piles_hw).
-compile(export_all).
start([]) -> 0;
start(List) ->
Total = lists:foldl(fun(X, Sum)-> X+Sum end,0,List),
if (Total rem 2) == 0 ->
Total/2,
copy_to_list_one([],List,start(List));
true ->
func_fail()
end.
copy_to_list_one(L1,[H|T],X)->
Y =lists:sum(L1)+H,
if Y<X ->
copy_to_list_one(lists:append(L1,[H]),lists:delete(H,[H|T]),X);
Y==X ->
take(lists:append(L1,[H]));
Y>X ->
copy_to_list_one(L1,lists:delete(H,[H|T]),X)
end;
copy_to_list_one(L1,[],X)->
copy_func_two([1,2,3,4,19,20,28,14,11],X).
copy_func_two([H|T],X)->
copy_to_list_one([],lists:append(T,[H]),X).
take(L3)->
io:format("~w",[L3]).
func_fail() ->
io:format("~n fail ~n").
But, in this way I go into an infinite loop sometimes. Could somebody help?
Edit:
Pascal was entirely correct: there is no algorithm (at least not that I could come up with) that can solve certain sets by running down the list one item at a time. (In particular when half the sum of the list equals X * N where X is present in the list N times.) I initially put a flawed algorithm here.
That got me excited in the nerdiest of ways, so here is an exhaustive algorithm involving the pairs of [{P, (List - P)} || P <- powerset(List)].
There are some lists:usort/1 shenanigans in there that I didn't clean up to uniquify the list prior to the final comparison (otherwise you get duplicate similar pairs, which is ugly). Anyway, ugly, but now correct:
comblit(List) ->
Power = powerset(List),
Lists = lists:usort([lists:sort([Z, lists:subtract(List, Z)]) || Z <- Power]),
Pairs = lists:map(fun([H|[B|[]]]) -> {H, B} end, Lists),
[{Z, X} || {Z, X} <- Pairs, lists:sum(Z) == lists:sum(X)].
powerset([H|T]) ->
Part = powerset(T),
powerset(Part, H, Part);
powerset([]) -> [[]].
powerset(A, Part, [H|T]) ->
powerset([[Part|H]|A], Part, T);
powerset(A, _, []) -> A.
This is still not a concurrent solution, but the path to making it concurrent is a lot more obvious now.
Thanks for pointing that out, Pascal. That was sort of fun.
I have this solution that is not concurrent:
-module(split).
-export([split/1,t_ok/0,t_too_long/0,t_fail/0,t_crash/0]).
%% [EDIT]
%% Don't use this code, it fails with negative integers!
% Exported
%% take a list and split it in 2 list which sum are equals
split(L=[_|_]) ->
T2 = lists:sum(L),
{ok, TRef} = timer:send_after(20000,too_long),
R = case T2 rem 2 of
1 -> {error,fail};
0 -> split(tl(L),[hd(L)],[],T2 div 2,hd(L),0)
end,
timer:cancel(TRef),
R.
% test
t_ok() -> split([1,2,3,4,5,6,7]).
t_too_long() -> split(lists:seq(1,3+4*100000)).
t_fail() -> split([2,4,6,10000,8,6]).
t_crash() -> split([]).
% private
split([H|Q],A,B,T,Asf,_Bsf) when H + Asf == T -> {ok,{[H|A],B ++ Q}};
split([H|Q],A,B,T,_Asf,Bsf) when H + Bsf == T -> {ok,{A ++ Q,[H|B]}};
split([H|Q],A,B,T,Asf,Bsf) when H + Asf > T, H + Bsf < T -> c_split(Q,A,[H|B],T,Asf,Bsf+H);
split([H|Q],A,B,T,Asf,Bsf) when H + Asf < T, H + Bsf > T -> c_split(Q,[H|A],B,T,Asf+H,Bsf);
split([H|Q],A,B,T,Asf,Bsf) when H + Asf < T, H + Bsf < T ->
case c_split(Q,A,[H|B],T,Asf,Bsf+H) of
{error,fail} -> c_split(Q,[H|A],B,T,Asf+H,Bsf);
R -> R
end;
split([],A,B,_T,_T,_T)-> {ok,{A,B}};
split(_,_,_,_,_,_) -> {error,fail}.
c_split(L,A,B,T,Asf,Bsf) ->
receive
too_long -> {error,too_long}
after 0 ->
split(L,A,B,T,Asf,Bsf)
end.
To turn it concurrent, you could replace the line 0 -> split(tl(L),[hd(L)],[],T2 div 2,hd(L),0) by a call to a function which spawn_link several processes (as much as there are core available) which start the split/6 function with different initial conditions. The split/6 must have a 7th parameter: the Pid of the main process where it will send back its answer. The main process wait for answers and stop
if a solution is found
if all processes fail to find one
if the time out occurs
I have edited the code following #Odobenus remark (but it still fail on [] -> {ok,[],[]} :o), and I also made a concurrent version. The funny thing is that for this kind of problem, and with the input list I use (a lists:seq) there are so many solution that any start sequence I choose can give a solution, so the concurrent version is slower.
I'm trying to create a list and print it out, counting down from N to 1. This is my attempt:
%% Create a list counting down from N to 1 %%
-module(list).
-export([create_list/1]).
create_list(N) when length(N)<hd(N) ->
lists:append([N],lists:last([N])-1),
create_list(lists:last([N])-1);
create_list(N) ->
N.
This works when N is 1, but otherwise I get this error:
172> list:create_list([2]).
** exception error: an error occurred when evaluating an arithmetic expression
in function list:create_list/1 (list.erl, line 6)
Any help would be appreciated.
You should generally avoid using append or ++, which is the same thing, when building lists. They both add elements to the end of a list which entails making a copy of the list every time. Sometimes it is practical but it is always faster to work at the front of the list.
It is a bit unclear in which order you wanted the list so here are two alternatives:
create_up(N) when N>=1 -> create_up(1, N). %Create the list
create_up(N, N) -> [N];
create_up(I, N) ->
[I|create_up(I+1, N)].
create_down(N) when N>1 -> %Add guard test for safety
[N|create_down(N-1)];
create_down(1) -> [1].
Neither of these are tail-recursive. While tail-recursion is nice it doesn't always give as much as you would think, especially when you need to call a reverse to get the list in the right order. See Erlang myths for more information.
The error is lists:last([N])-1. Since N is an array as your input, lists:last([N]) will return N itself. Not a number you expect. And if you see the warning when compiling your code, there is another bug: lists:append will not append the element into N itself, but in the return value. In functional programming, the value of a variable cannot be changed.
Here's my implementation:
create_list(N) ->
create_list_iter(N, []).
create_list_iter(N, Acc) ->
case N > 0 of
true -> NewAcc = lists:append(Acc, [N]),
create_list_iter(N-1, NewAcc);
false -> Acc
end.
If I correctly understand your question, here is what you'll need
create_list(N) when N > 0 ->
create_list(N, []).
create_list(1, Acc) ->
lists:reverse([1 | Acc]);
create_list(N, Acc) ->
create_list(N - 1, [N | Acc]).
If you work with lists, I'd suggest you to use tail recursion and lists construction syntax.
Also, to simplify your code - try to use pattern matching in function declarations, instead of case expressions
P.S.
The other, perhaps, most simple solution is:
create_list(N) when N > 0 ->
lists:reverse(lists:seq(1,N)).
I've been trying to get into F# on and off for a while but I keep getting put off. Why?
Because no matter which 'beginners' resource I try to look at I see very simple examples that start using the operator ->.
However, nowhere have I found as yet that provides a clear simple explanation of what this operator means. It's as though it must be so obvious that it doesn't need explanation even to complete newbies.
I must therefore be really dense or perhaps it's nearly 3 decades of previous experience holding me back.
Can someone please, explain it or point to a truly accessible resource that explains it?
'->' is not an operator. It appears in the F# syntax in a number of places, and its meaning depends on how it is used as part of a larger construct.
Inside a type, '->' describes function types as people have described above. For example
let f : int -> int = ...
says that 'f' is a function that takes an int and returns an int.
Inside a lambda ("thing that starts with 'fun' keyword"), '->' is syntax that separates the arguments from the body. For example
fun x y -> x + y + 1
is an expression that defines a two argument function with the given implementation.
Inside a "match" construct, '->' is syntax that separates patterns from the code that should run if the pattern is matched. For example, in
match someList with
| [] -> 0
| h::t -> 1
the stuff to the left of each '->' are patterns, and the stuff on the right is what happens if the pattern on the left was matched.
The difficulty in understanding may be rooted in the faulty assumption that '->' is "an operator" with a single meaning. An analogy might be "." in C#, if you have never seen any code before, and try to analyze the "." operator based on looking at "obj.Method" and "3.14" and "System.Collections", you may get very confused, because the symbol has different meanings in different contexts. Once you know enough of the language to recognize these contexts, however, things become clear.
It basically means "maps to". Read it that way or as "is transformed into" or something like that.
So, from the F# in 20 minutes tutorial,
> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]
The code (fun i -> i % 2 = 0) defines
an anonymous function, called a lambda
expression, that has a parameter x and
the function returns the result of "x
% 2 = 0", which is whether or not x is
even.
First question - are you familiar with lambda expressions in C#? If so the -> in F# is the same as the => in C# (I think you read it 'goes to').
The -> operator can also be found in the context of pattern matching
match x with
| 1 -> dosomething
| _ -> dosomethingelse
I'm not sure if this is also a lambda expression, or something else, but I guess the 'goes to' still holds.
Maybe what you are really referring to is the F# parser's 'cryptic' responses:
> let add a b = a + b
val add: int -> int -> int
This means (as most of the examples explain) that add is a 'val' that takes two ints and returns an int. To me this was totally opaque to start with. I mean, how do I know that add isn't a val that takes one int and returns two ints?
Well, the thing is that in a sense, it does. If I give add just one int, I get back an (int -> int):
> let inc = add 1
val inc: int -> int
This (currying) is one of the things that makes F# so sexy, for me.
For helpful info on F#, I have found that blogs are FAR more useful that any of the official 'documentation': Here are some names to check out
Dustin Campbell (that's diditwith.net, cited in another answer)
Don Symes ('the' man)
Tomasp.net (aka Tomas Petricek)
Andrew Kennedy (for units of measure)
Fsharp.it (famous for the Project Euler solutions)
http://lorgonblog.spaces.live.com/Blog (aka Brian)
Jomo Fisher
(a -> b) means "function from a to b". In type annotation, it denotes a function type. For example, f : (int -> String) means that f refers to a function that takes an integer and returns a string. It is also used as a contstructor of such values, as in
val f : (int -> int) = fun n -> n * 2
which creates a value which is a function from some number n to that same number multiplied by two.
There are plenty of great answers here already, I just want to add to the conversation another way of thinking about it.
' -> ' means function.
'a -> 'b is a function that takes an 'a and returns a 'b
('a * 'b) -> ('c * 'd) is a function that takes a tuple of type ('a, 'b) and returns a tuple of ('c, 'd). Such as int/string returns float/char.
Where it gets interesting is in the cascade case of 'a -> 'b -> 'c. This is a function that takes an 'a and returns a function ('b -> 'c), or a function that takes a 'b -> 'c.
So if you write:
let f x y z = ()
The type will be f : 'a -> 'b -> 'c -> unit, so if you only applied the first parameter, the result would be a curried function 'b -> 'c -> 'unit.
From Microsoft:
Function types are the types given to
first-class function values and are
written int -> int. They are similar
to .NET delegate types, except they
aren't given names. All F# function
identifiers can be used as first-class
function values, and anonymous
function values can be created using
the (fun ... -> ...) expression form.
Many great answers to this questions, thanks people. I'd like to put here an editable answer that brings things together.
For those familiar with C# understanding -> being the same as => lamba expression is a good first step. This usage is :-
fun x y -> x + y + 1
Can be understood as the equivalent to:-
(x, y) => x + y + 1;
However its clear that -> has a more fundemental meaning which stems from concept that a function that takes two parameters such as the above can be reduced (is that the correct term?) to a series of functions only taking one parameter.
Hence when the above is described in like this:-
Int -> Int -> Int
It really helped to know that -> is right associative hence the above can be considered:-
Int -> (Int -> Int)
Aha! We have a function that takes Int and returns (Int -> Int) (a curried function?).
The explaination that -> can also appear as part of type definiton also helped. (Int -> Int) is the type of any of function which takes an Int and returns an Int.
Also helpful is the -> appears in other syntax such as matching but there it doesn't have the same meaning? Is that correct? I'm not sure it is. I suspect it has the same meaning but I don't have the vocabulary to express that yet.
Note the purpose of this answer is not to spawn further answers but to be collaboratively edited by you people to create a more definitive answer. Utlimately it would be good that all the uncertainies and fluf (such as this paragraph) be removed and better examples added. Lets try keep this answer as accessible to the uninitiated as possible.
In the context of defining a function, it is similar to => from the lambda expression in C# 3.0.
F#: let f = fun x -> x*x
C#: Func<int, int> f = x => x * x;
The -> in F# is also used in pattern matching, where it means: if the expression matches the part between | and ->, then what comes after -> should be given back as the result:
let isOne x = match x with
| 1 -> true
| _ -> false
The nice thing about languages such as Haskell (it's very similar in F#, but I don't know the exact syntax -- this should help you understand ->, though) is that you can apply only parts of the argument, to create curried functions:
adder n x y = n + x + y
In other words: "give me three things, and I'll add them together". When you throw numbers at it, the compiler will infer the types of n x and y. Say you write
adder 1 2 3
The type of 1, 2 and 3 is Int. Therefore:
adder :: Int -> Int -> Int -> Int
That is, give me three integers, and I will become an integer, eventually, or the same thing as saying:
five :: Int
five = 5
But, here's the nice part! Try this:
add5 = adder 5
As you remember, adder takes an int, an int, an int, and gives you back an int. However, that is not the entire truth, as you'll see shortly. In fact, add5 will have this type:
add5 :: Int -> Int -> Int
It will be as if you have "peeled off" of the integers (the left-most), and glued it directly to the function. Looking closer at the function signature, we notice that the -> are right-associative, i.e.:
addder :: Int -> (Int -> (Int -> Int))
This should make it quite clear: when you give adder the first integer, it'll evaluate to whatever's to the right of the first arrow, or:
add5andtwomore :: Int -> (Int -> Int)
add5andtwomore = adder 5
Now you can use add5andtwomore instead of "adder 5". This way, you can apply another integer to get (say) "add5and7andonemore":
add5and7andonemore :: Int -> Int
add5and7andonemore = adder 5 7
As you see, add5and7andonemore wants exactly another argument, and when you give it one, it will suddenly become an integer!
> add5and7andonemore 9
=> ((add5andtwomore) 7) 9
=> ((adder 5) 7) 9)
<=> adder 5 7 9
Substituting the parameters to adder (n x y) for (5 7 9), we get:
> adder 5 7 9 = 5 + 7 + 9
=> 5 + 7 + 9
=> 21
In fact, plus is also just a function that takes an int and gives you back another int, so the above is really more like:
> 5 + 7 + 9
=> (+ 5 (+ 7 9))
=> (+ 5 16)
=> 21
There you go!