I am currently reading Programming in F# 3.0 and I read that F# supports partial function application.
But if I try
List.map (+1) [1 .. 10];;
Then I get error FS0001: This expression was expected to have type 'a -> 'b
but List.map (fun x -> x + 1) [1 .. 10];; compiles fine. Any ideas why?
I suppose you come from Haskell, for expecting it to work this way :)
Unfortunately, F# doesn't have the syntactic sugar where you can partially apply an operator by parenthesizing it preceded or followed by an expression. In your code, +1 is considered a single number token, which is why it complains that it is not a function.
What F# does have, however, is the syntax where you can parenthesize the operator alone. Which leads to #Lee's solution. Be careful about this syntax though: (+) 1 is equivalent to Haskell's (1+), not (+1). Obviously for addition it doesn't matter, but for asymmetrical operations such as subtraction, it can be misleading.
You need to put brackets around the +:
List.map ((+)1) [1..10]
Related
I am calling the string method "contains" in a lambda function, and would like to negate it. I thought this could be done with not myString.Contains("abbr") but it gives me the error
Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized
My actual function is this
open System.IO
let createWordArray filePath =
File.ReadLines(filePath)
|> Seq.filter (fun line -> line <> "")
|> Seq.filter (fun line -> not line.Contains("abbr.")) // Error occurs here
|> Seq.map (fun line -> line.Split(' ').[0])
|> Seq.filter (fun word -> word.StartsWith("-") || word.EndsWith("-"))
|> Seq.toArray
Please point out any other obvious mistakes I'm making.
You just need to add parentheses around the argument of the not function:
|> Seq.filter (fun line ->
not (line.Contains("abbr.")))
Without the parentheses, the compiler is interpreteing your code as a call to not with two arguments:
not (line.Contains) ("abbr.")
F# syntax is not like C# (or C, or C++, or Java)
In particular, F# does not use parentheses for passing function arguments. Instead, F# uses whitespace for that:
let x = f y z
You are, of course, free to enclose any terms in parentheses if you wanted to indicate the order of operations, or just for aesthetic reasons:
let x = f (y+5) z // parens for order of operations
let x = f (y) (z) // parens just for the heck of it
So you see, when you write:
line.Contains("abbr.")
There is no special meaning to the parens. You could just as well write this:
line.Contains "abbr."
It would be equivalent.
See what's happening? Not yet? Well, ok, let's try to add the not to the mix:
not line.Contains "abbr."
Is it clearer now? This looks like you're trying to call the not function, and you're giving it two arguments: first argument is line.Contains, and the second argument is "abbr."
This is not what you meant, right? What you meant was probably to first call line.Contains passing it "abbr " as argument, and then pass the result of that to not
The most straightforward way to do this is to use parentheses to indicate the order of operations:
not (line.Contains "abbr.")
Or, alternatively, you could use operator <|, which is intended specifically for this kind of thing. It just passes a parameter to a function, so pretty much does nothing. But its point is that it's an operator, so it's precedence is lower than a function call:
not <| line.Cobtains "abbr."
My attempt to do this is here (forgive the for loop - I was just curious to see if this was possible):
let (|>>) a (b : ('a -> unit) list) =
for x in b do
x a
but when I try to use it I get the error
That None of the types error message can occur if the function you're trying to use is defined further down the file or isn't imported correctly. Otherwise, your function definition seems ok.
I would discourage the use of a custom operator for this. I think they should be used very rarely. This one doesn't seem general enough to be worth defining and could make code hard to read. Here is one alternative:
[ printf "%A"; printfn "%A" ] |> List.iter ((|>) 1)
But it's even clearer and shorter to write out your operator definition inline:
for f in [ printf "%A"; printfn "%A" ] do f 1
I found it's very hard to search for the simple indentation guide in F#.
Basically, I am wondering what's the rule for multiple-line statement indentation.
In C#, there is no problem because whitespace doesn't count.
Although I can write F# code according to my intuition and it works, I really want to know what's the rule for breaking one statement into multiple lines.
I write as
printfn "%d"
1
It works as expected
And if I write them in the same column, something goes wrong.
>
printfn "%A%A"
1
[];;
> //nothing is returned... and no error in this case
I want to confirm the basic rule for doing this. It's a little annoying when you can't be sure what you are doing.
Thanks in advance
I just tried another case
List.iter
(printfn "%d")
[1..10];;
And it prints out 1 to 10.
Why it's not
List.iter
((printfn "%d")
[1..10]);;
As Yin points out, the rule is that arguments of a function should be indented further than the call to the function. To add more details, your first snippet is interpreted like this:
printfn "%A%A";
1;
[];
Each of these is a valid expression that returns something (function, number, empty list) and then ignores the result and continues. Because they are written in the top-level scope, F# Interactive doesn't emit a warning that you're ignoring some values. If they were in a do block or let declaration:
do
printfn "%A%A"
1
[]
The F# compiler would emit a warning when sequencing expressions (using ;) that do not return unit:
stdin(5,3): warning FS0193: This expression is a function value, i.e. is missing arguments. Its type is 'a -> 'b -> unit.
stdin(6,3): warning FS0020: This expression should have type 'unit', but has typ
e 'int'. Use 'ignore' to discard the result of the expression, or 'let' to bind
the result to a name.
stdin(5,3): warning FS0020: This expression should have type 'unit', but has typ
e ''a list'. Use 'ignore' to discard the result of the expression, or 'let' to b
ind the result to a name.
In your second example, you should indent:
>
printfn "%A%A"
1
[];;
Otherwise the three expressions are three sequential expressions, not a single expression.
You can refer F# Language Specification for firm rules, e.g. Chapter 15 in the specification.
In F# interactive, I can use String.Join("+", ["a"; "b"]) successfully, but
["a"; "b"] |> String.Join "+"
produces an error:
Script1.fsx(79,15): error FS0001: This expression was expected to have type
string list -> 'a
but here has type
string
How do I use String.Join passing a collection using pipeline?
P.S. The same problem is with lines |> File.WriteAllLines "filename.txt"
String.Join is a .NET method. When using a .NET method, F# views it as a function that takes a tuple as an argument (when calling it you write parameters as f(a, b)). The |> operator can be used with functions that use the curried form of parameters (and can be called by writing f a b).
You can use a function String.concat from the F# library (which does the same thing) instead:
["a"; "b"] |> String.concat "+"
EDIT File.WriteAllLines is the same case. If you want to use it as part of a pipeline, you can write an F# function that wraps the call:
let writeAllLines file (lines:seq<string>) =
System.IO.File.WriteAllLines(file, lines)
In general, you can use |> with .NET methods only if you want to write all arguments on the left side of the operator. You can for example write:
("+", ["a"; "b"]) |> System.String.Join
... but that doesn't fit with the usual use of pipeline operator. When working with .NET API, it is usually better to use a C#-like style of programming (without pipelining), because pipeline works well only with functional libraries.
I thought I would weigh in with an alternative. The OP specifically asked about String.Join, and Tomas Petricek's answer is absolutely correct for that method (use String.concat from the F# library).
If you're talking about another method that takes tupled arguments but you want to use them as curried, you can use this helper function:
let partial f x y = f(x, y)
This allows you to pass a method to 'partial' and get back a curried function. Use it like this:
let partial f x y = f(x, y)
myCollection |> partial String.Join "&"
A real F# noob question, but what is |> called and what does it do?
It's called the forward pipe operator. It pipes the result of one function to another.
The Forward pipe operator is simply defined as:
let (|>) x f = f x
And has a type signature:
'a -> ('a -> 'b) -> 'b
Which resolves to: given a generic type 'a, and a function which takes an 'a and returns a 'b, then return the application of the function on the input.
You can read more detail about how it works in an article here.
I usually refer to |> as the pipelining operator, but I'm not sure whether the official name is pipe operator or pipelining operator (though it probably doesn't really matter as the names are similar enough to avoid confusion :-)).
#LBushkin already gave a great answer, so I'll just add a couple of observations that may be also interesting. Obviously, the pipelining operator got it's name because it can be used for creating a pipeline that processes some data in several steps. The typical use is when working with lists:
[0 .. 10]
|> List.filter (fun n -> n % 3 = 0) // Get numbers divisible by three
|> List.map (fun n -> n * n) // Calculate squared of such numbers
This gives the result [0; 9; 36; 81]. Also, the operator is left-associative which means that the expression input |> f |> g is interpreted as (input |> f) |> g, which makes it possible to sequence multiple operations using |>.
Finally, I find it quite interesting that pipelining operaor in many cases corresponds to method chaining from object-oriented langauges. For example, the previous list processing example would look like this in C#:
Enumerable.Range(0, 10)
.Where(n => n % 3 == 0) // Get numbers divisible by three
.Select(n => n * n) // Calculate squared of such numbers
This may give you some idea about when the operator can be used if you're comming fromt the object-oriented background (although it is used in many other situations in F#).
As far as F# itself is concerned, the name is op_PipeRight (although no human would call it that). I pronounce it "pipe", like the unix shell pipe.
The spec is useful for figuring out these kinds of things. Section 4.1 has the operator names.
http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html
Don't forget to check out the library reference docs:
http://msdn.microsoft.com/en-us/library/ee353754(v=VS.100).aspx
which list the operators.