Consider the following code:
let pair = System.Tuple.Create (10, "foo") // val pair : int * string = (10, "foo")
let tuple = System.Tuple.Create <| (10, "foo") // val tuple : System.Tuple<int * string> = ((10, "foo"))
Why doesn't the two lines yield values of the same type? Does the type of the argument (10, "foo") somehow change between the two lines?
What's the exact difference between int * string and System.Tuple<int * string>?
For 2, at least the latter has null as a value (this is how this question came up). Are there other differences?
There are two different overloads of Tuple.Create:
Tuple.Create<'T1>(item1: 'T1)
Tuple.Create<'T1, 'T2>(item1: 'T1, item2: 'T2)
In the first case you just calling a method with two arguments. So the second Tuple.Create overload is obviously picked. No surprise.
But with piping you first create a tuple instance. And then pass it to Tuple.Create method. This is what happens in the second example
let intermediate : Tuple<int, string> = (10, "foo")
let tuple = Tuple.Create(intermediate)
With a single argument the first Tuple.Create overload will be picked.
Note: star type is a way tuple type names are written in F#. So Tuple<int, string, bool> will be (int * string * bool). It's the same thing.
Your tuple is a tuple of one (1) element, namely the tuple 10,"foo". It is equivalent of
System.Tuple.Create(System.Tuple.Create(10, "foo"))
Your pair on the other hand is a tuple of the two elements 10 and "foo".
So pair has type System.Tuple<int,string> (which is the same as int * string), but tuple has type System.Tuple<System.Tuple<int,string>> (which is System.Tuple<int * string>)
Related
I am new to F# and am trying to chain functions to make a Higher Order Function.
A simplified example is
init returns a tuple
validate accepts a tuple and returns bool
let init : string * string =
("1", "2")
let validate ((a: string), (b: string)) : bool =
a.Equals(b)
let test = init >> validate
ERROR
This expression was expected to have type 'a -> 'b' but here has type 'string * string'
As the answer for Piotr explains, you are getting an error because you have a value and a function. To compose those, you can turn init into a function, but you do not really need to use composition in this case.
If you want to pass a value as an argument to a function, it is typically much simpler to just pass it as an argument:
let res = validate init
Alternatively, if you have a number of functions you want to apply to your input in a sequence, you can do this using the piping operator:
let res = init |> validate
Function composition using >> is a nice functional trick, but I think it is actually much less common in standard F# code than most people think. I use |> all the time, but >> only rarely.
You can only compose functions using the >> combinator. Your first assignment is not a function - it is a binding to a value - your tuple.
You can convert it to a function just by adding empty parameter list () (unit) parameter like this:
let init() : string * string =
("1", "2")
let validate ((a: string), (b: string)) : bool =
a.Equals(b)
let test = init >> validate
let res = test()
I have the type declaration
type MYVAL = INT of int
and want to perform arithmetic operations on constants and variables of type MYVAL, like
let a : MYVAL = 10
let b : MYVAL = 25
let c = a+b
However, when I run it, it claims that MYVAL does not support the operator +. Isn't MYVAL treated as an integer type? If it is not, what does INT of int do? How would you perform arithmetic operations of variables and constants of type MYVAL?
MYVAL is not treated as an integer type. If that's what you want, you can use a type abbreviation; type MYVAL = int. I'm not sure why you would want to do that, but it's definitely possible.
In your current definition, MYVAL is a single case discriminated union. It wraps a given type, but doesn't inherit any of the underlying type's operators. By the way, the way to construct a an INT is let a = INT 10, not let a : MYINT = 10.
If you want, you can implement your own addition operator, like so
type MYVAL = INT of int with
static member (+) (INT a, INT b) = INT(a+b)
which would allow you to do
let a = INT 10
let b = INT 25
let c = a+b
You would need to do this for any operator you want to use, e.g. (-), (*), etc.
This might all seem a bit confusing, I mean why wouldn't we want the operators to be generated automatically? Well, if you're writing a parser, you might want to be able to read either an int or a string. Such a parser might output a value of a type type MYVAL = INT of int | STRING of string. How would (+) be defined, then? How about (-)?
In the parser example, MYVAL would no longer be a single case discriminated union, as it has multiple cases. A natural question to ask is, why are single case discriminated unions interesting, then? Who would want to use anything like that? Turns out, it's quite neat for subtyping. Say you want to represent a number that's higher than 10. One way to do this is
type HigherThan10 = private Value of int with
static member TryCreate(x: int) =
if x >= 10
then Some(Value(x))
else None
let x = Value(1) // Error
let y = HigherThan10.TryCreate(1) // None
let z = HigherThan10.TryCreate(10) // Some
I know it's not the most interesting example, but it may be used for representing an email adress as a 'subtype' of string. Notice, by the way, how this avoids using exceptions for control flow by returning a HigerThan10 option.
The reason why a simple sum doesn't work was already explained. I'll just show another option: you could define a map2 function for your type:
type MYVAL =
| INT of int
static member map2 f (INT x) (INT y) = INT (f x y)
//This is the correct way to initialize MYVAL, since it is a single-case discriminated union
let a = INT 10
let b = INT 25
//sum
MYVAL.map2 (+) a b //INT 35
//mult
MYVAL.map2 (*) a b //INT 250
//mod
MYVAL.map2 (%) a b //INT 5
If I have a square grid (created in WPF/XAML) in any size, with a given number of cells per side, it should be ridiculously easy to calculate the coordinates to a cell that was clicked by getting the mouse cursor position relative to the grid element. As I try to learn F#, I experience some problems with the syntax and would appreciate some input.
Here is an example of what I am trying to do:
// From a mouse event, fetch the position of the cursor relative to a IInputElement
let get_mouse_position (relative_to : IInputElement) (args : Input.MouseEventArgs) : (int*int) =
let position = args.GetPosition relative_to
((Convert.ToInt32(position.X) / cellsPerSide), (Convert.ToInt32(position.Y) / cellsPerSide))
// Get the position of the cursor relative to the grid
let get_cell_coordinates (element : IInputElement) =
get_mouse_position element
However, when I try to use the coordinates retrieved by calling get_cell_coordinates somewhere else where (x,y) coordinates are needed, I get an error that says:
This expression was expected to have type int * int but here has type 'a -> int * int
So, what am I doing wrong and why do I get this polymorph type and not just a tuple of integers?
The type you got is not a "polymorph" type, it's a function type. The reason you got a function of type 'a -> int * int instead of the int * int result you were expecting is because you didn't pass all the parameters to your function, so F# returned a function that expected the rest of the parameters. This is called "partial application", and you can read more about it here:
https://fsharpforfunandprofit.com/posts/currying/
and
https://fsharpforfunandprofit.com/posts/partial-application/
A quick summary of the two articles: in F#, all functions are treated as taking one parameter and returning one result. Yes, ALL functions. When you create a function that appears to take two parameters, F# rewrites it internally. It becomes a function that takes one parameter and returns a second function; this second function takes one parameter and returns the result. A concrete example will probably be useful at this point. Consider this function:
let doubleAndSubtract a b = (a * 2) - b
(Obviously, the parentheses around a * 2 aren't actually needed, but I left them in to make the function unambiguous to read).
Internally, F# actually rewrites this function into the following:
let doubleAndSubtract a =
let subtract b = (a * 2) - b
subtract
In other words, it builds a function that "closes over" (captures) the value of a that you passed in. So the following two functions are completely equivalent:
let explicitSubtract b = (5 * 2) - b
let implicitSubtract = doubleAndSubtract 5
If you type these functions in to the F# interactive prompt and look at the types that it declares each function to have, explicitSubtract has type b:int -> int, and implicitSubtract has type int -> int. The only difference between these two is that the type of explicitSubtract names the parameter, whereas implicitSubtract doesn't "know" the name of its parameter. But both will take an int, and return an int (specifically, 10 minus the parameter).
Now, let's look at the type signature for doubleAndSubtract. If you typed it into the F# interactive prompt, you'll have seen that its type signature is int -> int -> int. In type signatures, -> is right-associative, so that signature is really int -> (int -> int) -- in other words, a function that takes an int and returns a function that takes an int and returns an int. But you can also think of it as a function that takes two ints and returns an int, and you can define it that way.
So, what happened with your code here is that you defined the function like this:
let get_mouse_position (relative_to : IInputElement) (args : Input.MouseEventArgs) : (int*int) = ...
This is a function that takes two parameters (of types IInputElement and Input.MouseEventArgs) and returns a tuple of ints... but that's equivalent to a function that takes one parameter of type IInputElement, and returns a function that takes an Input.MouseEventArgs and returns a tuple of two ints. In other words, your function signature is:
IInputElement -> Input.MouseEventArgs -> (int * int)
When you called it as get_mouse_position element you passed it only a single parameter, so what you got was a function of type Input.MouseEventArgs -> (int * int). The type checker reported this as type 'a -> int * int (changing Input.MouseEventArgs into the generic type name 'a) for reasons I don't want to get into here (this is already rather long), but that's why you got the result you got.
I hope this helps you understand F# functions better. And do read those two articles I linked to; they'll take your understanding another step further.
I solved it by using the static Mouse.GetPosition method to obtain the position of the mouse instead of Input.MouseEventArgs.
The code now looks as follows, if anyone else has the same problem:
// From a mouse event, fetch the position of the cursor relative to a IInputElement
let get_mouse_position (relative_to : IInputElement) : (int*int) =
let position = Mouse.GetPosition relative_to
((Convert.ToInt32(position.X) / cellsPerSide), (Convert.ToInt32(position.Y) / 32))
// Get the position of the cursor relative to the input element
let get_cell_coordinates (element : IInputElement) =
get_mouse_position element
Can someone please explain what the major differences there are between Tuples and Dictionaries are and when to use which in Swift?
Major difference:
If you need to return multiple values from a method you can use tuple.
Tuple won't need any key value pairs like Dictionary.
A tuple can contain only the predefined number of values, in dictionary there is no such limitation.
A tuple can contain different values with different datatype while a dictionary can contain only one datatype value at a time
Tuples are particularly useful for returning multiple values from a function. A dictionary can be used as a model object.
There are two types of Tuple:
1 Named Tuple
In Named tuple we assign individual names to each elements.
Define it like:
let nameAndAge = (name:"Midhun", age:7)
Access the values like:
nameAndAge.name
nameAndAge.age
2 Unnamed Tuple
In unnamed tuple we don't specify the name for it's elements.
Define it like:
let nameAndAge = ("Midhun", 7)
Access the values like:
nameAndAge.0
nameAndAge.1
or
let (theName, thAge) = nameAndAge
theName
thAge
Reference:
Tuple
Tuples enable you to create and pass around groupings of values. You
can use a tuple to return multiple values from a function as a single
compound value.
You can check more about Tuple in Swift Programming Language
Dictionary
A dictionary is a container that stores multiple values of the same
type. Each value is associated with a unique key, which acts as an
identifier for that value within the dictionary
You can check more about Dictionary in Swift CollectionTypes
A tuple is completely predefined: it can only have the names and number of values you've predefined for it, though they can be different value types, and they don't have to have names. And the names are literals.
A dictionary can have any number of key-value pairs, of one value type. And the keys can be referred to through variables.
Here's a tuple (with names):
typealias MySillyTuple = (theInt:Int, theString:String)
That's it. There is one Int called theInt, one String called theString, and that is exactly what it must have, no more, no less. And the only way to access the values by name is as a literal: t.theInt. If you have a string "theInt", you can't use it to access t.theInt.
Here's a Dictionary:
var d = [String:String]()
Now d can have any number of keys, and any keys, from none to a gazillion. And the keys can be specified using string variables; you don't have to know in advance what a key will be. And all the values must be strings.
So basically I would say a tuple is nothing like a dictionary. A dictionary is a complex beast for look up by dynamic keys. A tuple is just a value that is more than one value.
Dictionary is Collection Type, Tuple is Compound type.
Dictionary is Key Value type, Tuple is Comma separated list of multiple types
Dictionary:
var dictionary = ["keyone": "value one", "keytwo": "Value Two"]
Tuple:
let someTuple: (Double, Double, String, (Int, Int)) = (3.14159, 2.71828, "Hello", (2, 3))
A dictionary is made up of key-value sets. A tuple is made for passing grouped values.
Dictionaries:
A dictionary is a container that stores multiple values of the same
type. Each value is associated with a unique key, which acts as an
identifier for that value within the dictionary.
A dictionary should be used for creating lists of associated objects. An example use would be a dictionary of players and their scores:
var scoreDictionary = ["Alice" : 100, "Bob" : 700]
Tuples:
Tuples group multiple values into a single compound value.
A tuple should be used for passing groups of values. They are similar to arrays, but are fixed-length and immutable. An example use might be a tuple representing a 3-dimensional point:
var myPoint = (10, 12, 14)
As you can see there are many cases in which you would use a dictionary and many cases in which you would use a tuple. Each has its own specific purpose.
Tuples are compound values, and can be useful for functions returning several values from a function. e.g. (from the Apple Docs):
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0]
var max = scores[0]
var sum = 0
for score in scores {
if score > max {
max = score
} else if score < min {
min = score
}
sum += score
}
return (min, max, sum)
}
This function returns a tuple containing min, max and sum. These values can be accessed either by name or position:
let statistics = calculateStatistics([5, 3, 100, 3, 9])
var sum:Int = statistics.sum
var sum2:Int = statistics.2
Dictionaries are "lookup" data types. They return an object for a given key. For example the following code:
let font:NSFont = NSFont(name: "AppleCasual", size: 18.0)!
let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as NSMutableParagraphStyle
textStyle.alignment = NSTextAlignment.LeftTextAlignment
let textColor:NSColor = NSColor(calibratedRed: 1.0, green: 0.0, blue: 1.0, alpha: 1.0)
let attribs = [NSFontAttributeName: font,
NSForegroundColorAttributeName: textColor,
NSParagraphStyleAttributeName: textStyle]
let color = attribs[NSForegroundColorAttributeName]
println("color = \(color)")
Will print:
color = Optional(NSCalibratedRGBColorSpace 1 0 1 1)
Dictionaries are useful for many things and are required for some functions. For example (after the code above):
let testString:NSString = "test String"
var img:NSImage = NSImage(size: NSMakeSize(200,200))
img.lockFocus()
testString.drawAtPoint(NSMakePoint(0.0, 0.0), withAttributes: attribs)
img.unlockFocus()
In this code drawAtPoint uses the dictionary attribs to lookup the parameters it needs. The parameters don't need to be in any specific order because drawAtPoint will lookup the values it needs by using the correct key.
Dictionaries and tuples are similar, but not quite the same. In the code above the dictionary returned an Optional type:Optional(NSCalibratedRGBColorSpace 1 0 1 1)
If we use a tuple for the same purpose:
var attribTuple = (font:NSFont(name: "AppleCasual", size: 18.0), color:NSColor(calibratedRed: 1.0, green: 0.0, blue: 1.0, alpha: 1.0))
println("tupleColor = \(attribTuple.color)")
Prints:
tupleColor = NSCalibratedRGBColorSpace 1 0 1 1
Not the optional type the dictionary did.
Tuples are fixed-length things. You can’t add an extra element to a tuple or remove one. Once you create a tuple it has the same number of elements – var t = (1,2) is of type (Int,Int). It can never become (1,2,3), the most you could do is change it to, say, (7,8). This is all fixed at compile-time.
You can access the elements via their numeric positions like this
t.0 + t.1 // with (1,2), would equal 3
t.0 = 7
Arrays are variable length: you can start with an array var a = [1,2], and then add an entry via a.append(3) to make it [1,2,3]. You can tell how many items with a.count. You can access/update elements via a subscript: a[0] + a[2] // equals 4
You can name the elements in tuples:
var n = (foo: 1, bar: 2)
Then you can use those names:
n.foo + n.bar // equals 3
This doesn’t remove the ability to access them by position though:
n.0 + n.1 // equals 3
But these names, once set, are fixed at compile time just like the length:
n.blarg // will fail to compile
This is not the same as dictionaries, which (like arrays), can grow or shrink:
var d = [“foo”:1, “bar”:2]
d[“baz”] = 3;
d[“blarg”] // returns nil at runtime, there’s no such element
Why is disabled types like
type t = A of int | B of string * mutable int
while such types are allowed:
type t = A of int | B of string * int ref
The question is, how would you modify the value of a mutable element of discriminated union case? For ref types, this is quite easy, because ref is a reference cell (a record actually) which contains the mutable value:
match tval with
| B(str, refNum) -> refNum := 4
We extract the reference cell and assign it to a new symbol (or a new variable) refNum. Then we modify the value inside the ref cell, which also modifies tval, because the two references to the cell (from discriminated union case and from refNum variable) are aliased.
On the other hand, when you write let mutable n = 0, you're creating a variable, which can be directly mutated, but there is no cell holding the mutable value - the variable n is directly mutable. This shows the difference:
let mutable a = 10
let mutable b = a
b <- 5 // a = 10, b = 5
let a = ref 10
let b = a
b := 5 // a = 5, b = 5 (because of aliasing!)
So, to answer your question - there is no way to directly refer to the value stored inside the discriminated union case. You can only extract it using pattern matching, but that copies the value to a new variable. This means that there isn't any way you could modify the mutable value.
EDIT
To demonstrate limitations of mutable values in F#, here is one more example - you cannot capture mutable values inside a closure:
let foo() =
let mutable n = 0
(fun () -> n <- n + 1; n) // error FS0407
I think the reason is same as with discriminated union cases (even though it's not as obvious in this case). The compiler needs to copy the variable - it is stored as a local variable and as a field in the generated closure. And when copying, you want to modify the same variable from multiple references, so aliasing semantics is the only reasonable thing to do...
Ref is a type (int ref = ref<int>). Mutable is not a type, it's a keyword that allows you to update a value.
Example:
let (bla:ref<int>) = ref 0 //yup
let (bla:mutable<int>) = 3 //no!