What is the '*' used for in this example? - f#

I am trying to figure out how to design a type for trees in F# and was looking at this thread for some help Tree Representation in F#.
In it, they define:
type Tree =
| Branch of string * Tree list
| Leaf of string
I am not sure what the * operator between string and Tree is supposed to do. I have been seeing it all over the place, but don't know what to search to find the answer.
Thanks!

This is the Tuple type name, from Microsoft Documentation
Names of Tuple Types
When you write out the name of a type that is a
tuple, you use the * symbol to separate elements. For a tuple that
consists of an int, a float, and a string, such as (10, 10.0, "ten"),
the type would be written as follows.
int * float * string

In types declarations, * (asterisk) indicates pairing in a tuple:
https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/tuples#names-of-tuple-types

Related

What does the type "string * string" mean in F#?

Tried searching everywhere.
Looking at https://github.com/fsharp/FAKE/blob/master/src/app/Fake.IIS/IISHelper.fs#L64 with parameter string * string.
Tried to instantiate in F# code and received error FS0010: Incomp
lete structured construct at or before this point in expression.
What in the world is this and how does on instantiate this?
string*string is a pair of two strings and is roughly equal to Tuple<string, string>. string*int*decimal is then roughly equal to Tuple<string, int, decimal>.
You create an instance of string*string using the following expression "first", "second". An instance of string*int*decimal is created like so "1", 2, 3.0M.
For more information on tuples see: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/tuples
The rationale for this notation is easier to see if you consider that F# has an algebra for creating types; * create tuples and | creates unions.
// Tree is roughly equal to having an interface Tree
// with three implementations Empty, Leaf and Fork
type Tree<'T> =
| Empty
| Leaf of 'T
| Fork of Tree<'T>*Tree<'T>
Having an algebra for type creation is very powerful as Scott Wlaschin demonstrates: https://fsharpforfunandprofit.com/ddd/

Use non Discriminated Union types from F# in C#

I have declared some data types in a F# library that I want to fill from C# code. The problem I encountered is that only DU's get "exported" as a class, consider this example file Test.fs:
module Test
type SimpleType = string
type SimpleList = string list
type SimpleDU =
| A
| B
type SimpleRecord = { Text : string }
I was confused at first when just referencing the F# project wouldn't allow me use the SimpleType and SimpleList types in C#. I looked at the resulting F# library with ILDasm and found only code for the SimpleDU and SimpleRecord type which are perfectly accessible in C# code.
Is there a way to "export" non DU types so they are usable in C# or do I have to declare every non DU type as an explicit record?
The definitions of
type SimpleType = string
type SimpleList = string list
are type abbreiviations which are eliminated during type checking and do not create new types. These are described in the specifition:
8.3 Type Abbreviations
Type abbreviations define new names for other types. For example:
type PairOfInt = int * int
Type abbreviations are expanded and erased during compilation and do
not appear in the elaborated form of F# declarations, nor can they be
referred to or accessed at runtime.

F# operator overloading strange behavoir

Let's say that for some strange reason I want to have this function:
let (~-) (str:string) = 42
So I can do something like this and get 42 as result:
-"test"
val it : int = 42
Which is fine. But now when I do:
let a = 100
-a
I get:
error FS0001: This expression was expected to have type
string
but here has type
int
Any idea why is this happening?
When you define operators using let, the new definition hides all previous definition of the operator. So in your example, you are hiding the default implementation of the unary minus (which works for numbers) and replacing it with a new operator that only works on strings.
It is not easy to re-define overloaded operators on built-in types. If you need that, it is probably better idea to avoid using operators (just use a function). However, if you want to provide an overloaded operator for a custom type, you can do this by adding operator as a static member:
type MinusString(s:string) =
member x.Value = s
/// Provide unary minus for MinusString values
static member (~-) (ms:MinusString) =
MinusString("-" + ms.Value)
-(MinusString "hi") // Returns "-hi"
If you really want to redefine built-in operator like unary minus and make it work on string, then there is actually a way to do this using a trick described in earlier SO answers. However, I would only use this if you have a good reason.
Simply, you overwrote the minus operator with one that takes a string and returns an int, then tried to apply it to an int, which it can't do anymore.

Can I use a type within its own type definition?

I'm trying to define the following type:
type lToken =
LInt of int
| LString of string
| LList of lToken list
| LFunction of string * LList
but I'm getting an error 'LList' is not defined.
Is there a way to do what I'm trying to do - i.e. use the types I'm defining inside their own type definition?
Thanks
As others pointed out, LList is not a name of a type, but just a name of discriminated union's constructor. In F#, cases of discriminated union happen to be compiled as .NET types, but that's just an implementation detail and you cannot refer to the generated types.
If you want to declare LFunction as a cast that consists of string and a LList then you can either expand the definition (as Brian and Marcelo suggest) or declare a new type (using type .. and to declare recursive types):
type List = Token list
and Token =
| LInt of int
| LString of string
| LList of List
| LFunction of string * List
PS: If you're writing F# then I'd recommend following standard naming guidelines and using PascalCase with a more descriptive name for type names. What does "l" stand for? Could you expand it (thanks to type inference, you won't need to write the type name anyway).
LList is a constructor, not a type. Just use the associated type directly:
...
| LFunction of string * (lToken list)
(My ML is very rusty; I'm not sure whether the parentheses are right.)
LList is not the name of a type; lToken is. Perhaps you want lToken list there instead?

Questions about the definition of lazy

On line 5633 in prim-types.fs (v1.9.7.8) there is the following type abbreviation:
type 'T ``lazy`` = Lazy<'T>
I have a few questions about it.
What do the double backticks mean?
Is this definition equivalent to type lazy<'T> = Lazy<'T>? (If not, how is it different?)
The double back ticks are a way of allowing an F# keyword to be used as an identifier. Another example would be
let ``let`` = 42
To answer the second half of your question, generic types in F# can be specified using either the O'Caml-style syntax where the generic parameter precedes the type (e.g 'a list, int array, etc.), or the .NET-style with angle brackets (e.g. list<'a>, array<int>, etc.), so the two definitions are indeed basically equivalent (except that your version as written is syntactically invalid because lazy is a keyword). For multi-parameter generic types, the O'Caml style is deprecated and will generate a warning (e.g. let (m:(int,string) Map) = Map.empty should be rewritten as let (m:Map<int,string>) = Map.empty).

Resources