Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible in F# to curry a middle function argument?

Tags:

currying

f#

Here's code that works fine:

let f x y z = x + y + z

let g x y = f x y
let h x z = z |> f x

So I can write expression "h 1", and FSI displays:

val it : (int -> int -> int) = <fun:it@110-3>

If I call "h 1 2 3", the arguments are applied in the right order.
But if the last argument has a different type, things get different:

let ff x y (z : string) = x + y

let gg x y = ff x y
let hh x (z : string) = z |> ff x

Now the last function hh causes an error message:

Script.fsx(119,10): error FS0001: Type mismatch. Expecting a string -> 'a but given a int -> string -> int. The type string does not match the type int

I understand why this happens - "z" is appended to "ff x" making it a second argument. But then I'd expect in the first example expression "h 1 2 3" not to work properly (being executed as "f 1 3 2"). But it works just fine.

like image 833
Vagif Abilov Avatar asked Jul 07 '10 12:07

Vagif Abilov


People also ask

Is there any orbital after f?

After f, orbitals are simply labelled alphabetically, so the sequence is s, p, d, f, g, h, i, .... The rules for electron aufbau, i.e., how electrons are placed in orbitals, are given by the following rough scheme. 1. Electrons are always added in order of increasing energy.

Why is the f orbital not possible?

Thus, due to the energy of the shell and the number of electrons that are able to occupy each orbital. The orbitals like $ 2d,1d, $ and $ 3f $ orbitals do not exist.

How many orbitals are in f?

An f sublevel has 7 orbitals.

What quantum numbers are not allowed?

Rules Governing the Allowed Combinations of Quantum NumbersThe principal quantum number (n) cannot be zero. The allowed values of n are therefore 1, 2, 3, 4, and so on. The angular quantum number (l) can be any integer between 0 and n - 1. If n = 3, for example, l can be either 0, 1, or 2.


1 Answers

The functions ff and gg in your example are the same - the pipelining operator provides value for a first argument of a function on the right-hand side. In your example, the function on the right hand side is ff x and by using the pipelining operator, you specify the value for argument y:

let ff x y (z : string) = 
  printfn "%s" z
  x + y

// These two functions are the same:
let gg x y = ff x y
let hh x y = y |> ff x

There is no stnadard syntax for specifying other than first parameters when using partial function application. However, you can write a higher-order function or a custom operator to do that. For example:

// Takes a function 'f' of type 'b -> 'a -> 'c
// and a value 'v' of type 'a and creates a function
// that takes the first argument ('b -> 'c)
let (|*>) v f = (fun mid -> f mid v);;

let gg x y = ff x y     // Specifies arguments x and y
let hh x z = z |*> ff x // Specifies arguments x and z

I named the operator |*> to denote that it skips one argument. You could define operators that specify value of other arguments similarly (e.g. |**> to skip the first two arguments).

like image 200
Tomas Petricek Avatar answered Oct 29 '22 04:10

Tomas Petricek