I am currently learning F# with a free online resource. Since i am curious and try to apply the learned stuff in some small excercises, I find myself consulting the MSDN F# documentation quite often.
But the documentation seems really cryptic to me. Take this documentation page for the pown
function for example. The usage is pretty straight forward, but i don't understand the functions signature:
// Signature:
pown : ^T -> int -> ^T (requires ^T with static member One and ^T with static member op_Multiply and ^T with static member (/))
Can someone explain to me, what the following things are about?
I hope this isn't too much to cover in one answer.
A higher aperture (e.g., f/16) means less light is entering the camera. This setting is better for when you want everything in your shot to be in focus — like when you're shooting a group shot or a landscape. A lower aperture means more light is entering the camera, which is better for low-light scenarios.
With a larger opening (or a smaller f-stop number) you'll allow more light to enter. With a smaller opening (or a larger f-stop number) you'll allow less light to enter. By controlling the amount of light entering the lens, you're also controlling the overall exposure of the image.
(Focal-STOP) The f-stop is the "aperture" opening of a camera lens, which allows light to come in. It also determines how much is in focus in front of and behind the subject (see depth of field). The f-stop is one of the two primary measurements of a camera lens.
So, to summarize: focal length is a measure of the angle a lens sees over while f numbers are an inverse indicator of how much light a lens transmits at a given aperture position.
T
is a statically resolved type parameter as opposed to a normal generic type parameter (see also 4 below).->
is the type constructor for functions and is right associative, so this part is equivalent to ^T -> (int -> ^T)
. In other words, if you pass an argument of type ^T
to this function, you'll get back a function from int
to ^T
. So pown 2
is the function 2x where the power hasn't been passed yet. And pown 2 8
is the same as (pown 2) 8
: it's 28.^T
it must be statically known to meet these requirements. So you can call pown 2 8
(because int
supports these operations), but not pown "test" 8
(because string
doesn't).There are a few things going on there, so for starters, here's how I would suggest you approach signatures in F#. First of all, ignore the circumflex - mentally substitute a tick there. Then you can ignore the "requires" part - long story short, it's there because of the circumflex.
So after that you have a signature like this:
// Signature:
pown : 'T -> int -> 'T
'T
is a generic type - uppercase 'T
is a .NET standard, F# usually uses lowercase 'a
, 'b
etc. What this signature describes is a function that takes a 'T
and an int
, and returns a 'T
. The type after the last ->
is the "return type" of the function - at least that's a useful way to think about it at the beginning.
In reality, there's a bit more to that - in F# functions are curried (and partially applicable by default), so what you really have is a function that takes a 'T
and returns a function of signature int -> 'T
- at which point it's clear why you have double ->
.
And the circumflex thing is a statically resolved type - I see @kvb gave more details on that already. It's good to be aware that it exists, but it's something that's rarely used in practice (you'll see it on core numeric functions and operators though).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With