Why can't you write "(: :) 1 [2]" how can you write "(+) 1 2" in F #?

Put the fix-infix operator in parentheses and it behaves like a function,

let foo = (*) 3 2 // foo = 6 let factorial n = [2..n] |> List.fold (*) 1 // n! 

However, this does not work with the operator :: operator (cons),

 let ls = (::) 1 [2..5] // Error: Unexpected symbol '::' in binding. 

What is the reason for this?

+5
source share
2 answers

Because (::) (and [] , for that matter) is a symbolic keyword, you cannot expect to use it as an infix operator. See Specification F # , section 3.6 Symbolic Keywords.

In this case, you need to define an additional function, for example.

 let cons x xs = x :: xs let ls = cons 1 [2..5] 
+6
source

You can use the static method:

 let ls = List.Cons (1, [2..5]) 

or the operatorโ€™s detailed name:

 let ls = op_ColonColon (1, [2..5]) 

(noted with F # 3.0, older versions may behave differently. For example, MSDN offers op_Cons )

In both cases, there is no way to deduce the arguments. Numeric operators are defined as follows:

 let inline ( * ) (x:int) (y:int) = ... 

List concatenation, however, requires a tuple, and this also answers your question,

What is the reason for this?

In fact, (::) not a normal operator (a standalone function or type element), but a union case . Here's how List<'T> is defined in F # sources :

 type List<'T> = | ([]) : 'T list | (::) : Head: 'T * Tail: 'T list -> 'T list 

So, if your goal is to partially apply the arguments, the only good solution would be to write a wrapper function, as @pad suggested.

+8
source

Source: https://habr.com/ru/post/1201106/


All Articles