diff options
author | Mikhail Melnikov <mikhail_melnikov@epam.com> | 2017-11-30 15:02:24 +0300 |
---|---|---|
committer | Joel Martinez <joelmartinez@gmail.com> | 2017-11-30 18:51:54 +0300 |
commit | f8cdfc060fc8df64af4fb7f131ea8c0627d48258 (patch) | |
tree | 36bc4370f3a136a2aacff2c7fe9988ea911795a6 /mdoc/mdoc.Test/mdoc.Test.FSharp | |
parent | b070267b5cf3986cdd79f52244a15412d0cbf70a (diff) |
mdoc: Support for F# signatures
Added F# signatures and usage formatter
Added unit and integration tests
Closes #108
Diffstat (limited to 'mdoc/mdoc.Test/mdoc.Test.FSharp')
43 files changed, 1912 insertions, 0 deletions
diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/AbstractClasses.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/AbstractClasses.fs new file mode 100644 index 00000000..2069fb4d --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/AbstractClasses.fs @@ -0,0 +1,66 @@ +module AbstractClasses + +// An abstract class that has some methods and properties defined +// and some left abstract. +[<AbstractClass>] +type Shape2D(x0 : float, y0 : float) = + let mutable x, y = x0, y0 + let mutable rotAngle = 0.0 + + // These properties are not declared abstract. They + // cannot be overriden. + member this.CenterX with get() = x and set xval = x <- xval + + // These properties are abstract, and no default implementation + // is provided. Non-abstract derived classes must implement these. + abstract Area : float with get + + // This method is not declared abstract. It cannot be + // overriden. + member this.Move dx dy = + x <- x + dx + y <- y + dy + + + // An abstract method that is given a default implementation + // is equivalent to a virtual method in other .NET languages. + // Rotate changes the internal angle of rotation of the square. + // Angle is assumed to be in degrees. + abstract member Rotate: float -> unit + default this.Rotate(angle) = rotAngle <- rotAngle + angle + + abstract member Rotate2: float -> unit + member this.Rotate3: float -> unit = fun(ff) -> () + + + +type Square(x, y, sideLengthIn) = + inherit Shape2D(x, y) + member this.SideLength = sideLengthIn + override this.Area = this.SideLength * this.SideLength + override this.Rotate2(angle) = () + +type Circle(x, y, radius) = + inherit Shape2D(x, y) + let PI = 3.141592654 + member this.Radius = radius + override this.Area = PI * this.Radius * this.Radius + // Rotating a circle does nothing, so use the wildcard + // character to discard the unused argument and + // evaluate to unit. + override this.Rotate(_) = () + //override this.Name = "Circle" + override this.Rotate2(angle) = () + +let square1 = new Square(0.0, 0.0, 10.0) +let circle1 = new Circle(0.0, 0.0, 5.0) +circle1.CenterX <- 1.0 +square1.Move -1.0 2.0 +square1.Rotate 45.0 +circle1.Rotate 45.0 + +let shapeList : list<Shape2D> = [ (square1 :> Shape2D); + (circle1 :> Shape2D) ] +List.iter (fun (elem : Shape2D) -> + printfn "Area of %s: %f" (elem.ToString()) (elem.Area)) + shapeList
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Accessibility.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Accessibility.fs new file mode 100644 index 00000000..90eb2aeb --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Accessibility.fs @@ -0,0 +1,28 @@ +module Accessibility + +// This type is not usable outside of this file +type private MyPrivateType() = + // x is private since this is an internal let binding + let x = 5 + // X is private and does not appear in the QuickInfo window + // when viewing this type in the Visual Studio editor + member private this.X() = 10 + member this.Z() = x * 100 + +type internal MyInternalType() = + let x = 5 + member private this.X() = 10 + member this.Z() = x * 100 + +// Top-level let bindings are public by default, +// so "private" and "internal" are needed here since a +// value cannot be more accessible than its type. +let private myPrivateObj = new MyPrivateType() +let internal myInternalObj = new MyInternalType() + +// let bindings at the top level are public by default, +// so result1 and result2 are public. +let result1 = myPrivateObj.Z +let result2 = myInternalObj.Z + + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/AccessibilityTest.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/AccessibilityTest.fs new file mode 100644 index 00000000..4fd4fb9a --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/AccessibilityTest.fs @@ -0,0 +1,10 @@ +module AccessibilityTest + +open Accessibility + +// The following line is an error because private means +// that it cannot be accessed from another file or module +// let private myPrivateObj = new MyPrivateType() +let internal myInternalObj = new MyInternalType() + +let result = myInternalObj.Z
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Animals.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Animals.fs new file mode 100644 index 00000000..8cc5ae6c --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Animals.fs @@ -0,0 +1,17 @@ +module Animals + +// Call a base class from a derived one. +type Animal() = + member __.Rest() = () + +type Dog() = + inherit Animal() + member __.Run() = + base.Rest() + +// Upcasting is denoted by :> operator. +let dog = Dog() +let animal = dog :> Animal + +//Dynamic downcasting (:?>) might throw an InvalidCastException if the cast doesn't succeed at runtime. +let shouldBeADog = animal :?> Dog diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/AssemblyInfo.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/AssemblyInfo.fs new file mode 100644 index 00000000..c2f7d9f7 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace mdoc.Test.FSharp.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[<assembly: AssemblyTitle("mdoc.Test.FSharp")>] +[<assembly: AssemblyDescription("")>] +[<assembly: AssemblyConfiguration("")>] +[<assembly: AssemblyCompany("EPAM Systems")>] +[<assembly: AssemblyProduct("mdoc.Test.FSharp")>] +[<assembly: AssemblyCopyright("Copyright © EPAM Systems 2017")>] +[<assembly: AssemblyTrademark("")>] +[<assembly: AssemblyCulture("")>] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[<assembly: ComVisible(false)>] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[<assembly: Guid("979f9f80-12fe-4236-9e93-6d554ab13701")>] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [<assembly: AssemblyVersion("1.0.*")>] +[<assembly: AssemblyVersion("1.0.0.0")>] +[<assembly: AssemblyFileVersion("1.0.0.0")>] + +do + ()
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Attributes.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Attributes.fs new file mode 100644 index 00000000..65cf8cbb --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Attributes.fs @@ -0,0 +1,22 @@ +module Attributes + +open System + + +type OwnerAttribute(name : string) = + inherit System.Attribute() + +type CompanyAttribute(name : string) = + inherit System.Attribute() + + +[<Owner("Jason Carlson")>] +[<Company("Microsoft")>] +type SomeType1 = class end + + + +[<AttributeUsage(AttributeTargets.Event ||| AttributeTargets.Module ||| AttributeTargets.Delegate, AllowMultiple = false)>] +type TypeWithFlagAttribute = class + member this.X = "F#" +end
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/ClassMembers.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/ClassMembers.fs new file mode 100644 index 00000000..99476946 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/ClassMembers.fs @@ -0,0 +1,27 @@ +module ClassMembers + +type PointWithCounter(a: int, b: int) = + // A variable i. + let mutable i = 0 + + // A let binding that uses a pattern. + let (x, y) = (a, b) + + // A private function binding. + let privateFunction x y = x * x + 2*y + + // A static let binding. + static let mutable count = 0 + + // A do binding. + do + count <- count + 1 + + member this.Prop1 = x + member this.Prop2 = y + member this.CreatedCount = count + member this.FunctionValue = privateFunction x y + +let point1 = PointWithCounter(10, 52) + +printfn "%d %d %d %d" (point1.Prop1) (point1.Prop2) (point1.CreatedCount) (point1.FunctionValue)
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Collections.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Collections.fs new file mode 100644 index 00000000..53f945df --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Collections.fs @@ -0,0 +1,6 @@ +module Collections +open FSharp.Collections + +let f (x:Map<int, int>) = 0 + +let f2 (x:seq<int>) = 0 diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Constraints.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Constraints.fs new file mode 100644 index 00000000..a80aed38 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Constraints.fs @@ -0,0 +1,86 @@ +module Constraints + +// Base Type Constraint +type Class1<'T when 'T :> System.Exception>() = + class end + +// Interface Type Constraint +type Class2<'T when 'T :> System.IComparable>() = + class end + +// Interface Type Constraint +type Class2_1<'T when 'T :> System.IComparable and 'T :> System.Exception>() = + class end + +// Null constraint +type Class3<'T when 'T : null>() = + class end + +// Member constraint with static member +type Class4<'T when 'T : (static member staticMethod1 : unit -> 'T) >() = + class end + +// Member constraint with instance member +type Class5<'T when 'T : (member Method1 : 'T -> int)>() = + class end + +// Member constraint with property +type Class6<'T when 'T : (member Property1 : int)>() = + class end + +// Constructor constraint +type Class7<'T when 'T : (new : unit -> 'T)>() = + class end + //member val Field = new 'T() + +// Reference type constraint +type Class8<'T when 'T : not struct>() = + class end + +// Enumeration constraint with underlying value specified +type Class9<'T when 'T : enum<uint32>>() = + class end + +// 'T must implement IComparable, or be an array type with comparable +// elements, or be System.IntPtr or System.UIntPtr. Also, 'T must not have +// the NoComparison attribute. +type Class10<'T when 'T : comparison>() = + class end + +// 'T must support equality. This is true for any type that does not +// have the NoEquality attribute. +type Class11<'T when 'T : equality>() = + class end + +type Class12<'T when 'T : delegate<obj * System.EventArgs, unit>>() = + class end + +type Class13<'T when 'T : unmanaged>() = + class end + +// If there are multiple constraints, use the and keyword to separate them. +type Class14<'T,'U when 'T : equality and 'U : equality>() = + class end + +type Class15() = class + // Member constraints with two type parameters + // Most often used with static type parameters in inline functions + static member inline add(value1 : ^T when ^T : (static member (+) : ^T * ^T -> ^T), value2: ^T) = + value1 + value2 + + // ^T and ^U must support operator + + static member inline heterogenousAdd(value1 : ^T when (^T or ^U) : (static member (+) : ^T * ^U -> ^T), value2 : ^U) = + value1 + value2 +end + +type Class16() = class + static member inline method(value1 : ^T when ^T : (static member (+) : ^T * ^T -> ^T), value2: ^T) = () +end + +type Class17() = class + static member method<'T when 'T : null>(value1 : 'T, value2: 'T) = () +end + +type Class18() = class + static member method(value1 : ^T, value2: ^T) = () +end
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Constructors.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Constructors.fs new file mode 100644 index 00000000..4d60f190 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Constructors.fs @@ -0,0 +1,315 @@ +module Constructors + +type MyClass(x0, y0, z0) = + let mutable x = x0 + let mutable y = y0 + let mutable z = z0 + do + printfn "Initialized object that has coordinates (%d, %d, %d)" x y z + member this.X with get() = x and set(value) = x <- value + member this.Y with get() = y and set(value) = y <- value + member this.Z with get() = z and set(value) = z <- value + new() = MyClass(0, 0, 0) + +type MyClassObjectParameters(x0:string, y0, z0) = + let mutable x = x0 + let mutable y = y0 + let mutable z = z0 + member this.X with get() = x and set(value) = x <- value + member this.Y with get() = y and set(value) = y <- value + member internal this.Z with get() = z and set(value) = z <- value + +// new() = MyClassObjectParameters("", 0, 0) +// new(x0:string) = MyClassObjectParameters("", x0, x0) + +type MyStruct = + struct + val X : int + val Y : int + val Z : int + new(x, y, z) = { X = x; Y = y; Z = z } + end + +let myStructure1 = new MyStruct(1, 2, 3) + + +// Error Each argument of the primary constructor for a struct must be given a type, +// for example 'type S(x1:int, x2: int) = ...'. +// These arguments determine the fields of the struct + +type MyStruct2 = + struct + [<DefaultValue>] + val mutable X : int + + [<DefaultValue>] + val mutable Y : int + + [<DefaultValue>] + val mutable Z : int + end + +let myStructure2 = new MyStruct2() + + + +type MyClass3 = + val a : int + val b : int + // The following version of the constructor is an error + // because b is not initialized. + // new (a0, b0) = { a = a0; } + // The following version is acceptable because all fields are initialized. + new(a0, b0) = { a = a0; b = b0; } + + +type MyClass3_1 (a0, b0)= + let a : int = a0 + let b : int = b0 + //val c : int + +type MyClass3_2 = + val a : int + member this.b : int = 19 + +type MyClass3_3() = + [<DefaultValue>] val mutable internal a : int + [<DefaultValue>] val mutable b : int + +type MyClass3_4 (a0, b0) = + [<DefaultValue>] val mutable a : int + [<DefaultValue>] val mutable b : int + +let myClassObj = new MyClass3(35, 22) +printfn "%d %d" (myClassObj.a) (myClassObj.b) + +// type MyStruct3 (a0, b0) = +// Each argument of the primary constructor for a struct must be given a type, +// for example 'type S(x1:int, x2: int) = ...'. +// These arguments determine the fields of the struct +type MyStruct33 (a0:int, b0:int) = + struct + [<DefaultValue>] val mutable a : int + [<DefaultValue>] val mutable b : int + + new (a0:int) = MyStruct33(a0, 0) + new (a0:int, b0:int, c0:int) = MyStruct33(a0, b0) + end + +let myStruct = new MyStruct33() +let myStruct2 = new MyStruct33(10, 15) + +type MyStruct44 (a0:int, b0:int) = + struct + [<DefaultValue>] val mutable a : int + [<DefaultValue>] val mutable b : int + end + + +type MyStruct55 (a0:int, b0:int) = + struct + [<DefaultValue>] val mutable a : int + [<DefaultValue>] val mutable b : int + new (a0:int) = MyStruct55(34, 12) //then {this.a = 71} + end + +type MyStruct66 = + struct + val a : int + val b : int + new (a0:int) = {a = a0; b = 83} + end + +type MyStruct77 = + struct + [<DefaultValue>] val mutable a : int + val b : int +// new (a0:int) = {b = 83; a = 12} // doesn't work + new (a0:int) = {b = 83} + end + +type MyStruct88 = + struct + [<DefaultValue>] val mutable a : int + val b : int +// new (a0:int) = {b = 83; a = 12} // doesn't work + new (a0:int) = {b = 83} + new (a0:int, b0:int) = {b = 87} + end + + + +type PetData = { + name : string + age : int + animal : string +} + +type Pet(name:string, age:int, animal:string) = + let mutable age = age + let mutable animal = animal + + new (name:string) = + Pet(name, 5, "dog") + + new (data:PetData) = + Pet(data.name, data.age, data.animal) then System.Console.WriteLine("Pet created from PetData") + + + +type public MyType = + val private myvar: int + val private myvar2: string + + new () = + for i in 1 .. 10 do + printfn "Before field assignments %i" i + { myvar = 1; myvar2 = "test" } + then + for i in 1 .. 10 do + printfn "After field assignments %i" i + + + + +//A primary constructor in a class can execute code in a do binding. +// However, what if you have to execute code in an additional constructor, without a do binding? +// To do this, you use the then keyword. + + // Executing side effects in the primary constructor and +// additional constructors. +type Person(nameIn : string, idIn : int) = + let mutable name = nameIn + let mutable id = idIn + do printfn "Created a person object." + member this.Name with get() = name and set(v) = name <- v + member this.ID with get() = id and set(v) = id <- v + new() = + Person("Invalid Name", -1) + then + printfn "Created an invalid person object." + new(person : Person) = + Person(person.Name, person.ID) + then + printfn "Created a copy of person object." + +let person1 = new Person("Humberto Acevedo", 123458734) +let person2 = new Person() +let person3 = new Person(person1) + + + + +// Self Identifiers in Constructors +// In other members, you provide a name for the current +// object in the definition of each member. +// You can also put the self identifier on the first line of the class definition +// by using the as keyword immediately following the constructor parameters. +// The following example illustrates this syntax.+ +type MyClass1(x) as this = + // This use of the self identifier produces a warning - avoid. + let x1 = this.X + // This use of the self identifier is acceptable. + do printfn "Initializing object with X =%d" this.X + member this.X = x + + + +// In additional constructors, you can also define a self identifier +// by putting the as clause right after the constructor parameters. +// The following example illustrates this syntax. +type MyClass2(x : int) = + member this.X = x + new() as this = MyClass2(0) then printfn "Initializing with X = %d" this.X + + + +// Assigning Values to Properties at Initialization +// You can assign values to the properties of a class object in the initialization code +// by appending a list of assignments of the form property = value +// to the argument list for a constructor. This is shown in the following code example. +type Account() = + let mutable balance = 0.0 + let mutable number = 0 + let mutable firstName = "" + let mutable lastName = "" + member this.AccountNumber + with get() = number + and set(value) = number <- value + member this.FirstName + with get() = firstName + and set(value) = firstName <- value + member this.LastName + with get() = lastName + and set(value) = lastName <- value + member this.Balance + with get() = balance + and set(value) = balance <- value + member this.Deposit(amount: float) = this.Balance <- this.Balance + amount + member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount + + +let account1 = new Account(AccountNumber=8782108, + FirstName="Darren", LastName="Parker", + Balance=1543.33) + + + + +// The following version of the previous code illustrates the combination +// of ordinary arguments, optional arguments, and property settings in one constructor call. +type Account2(accountNumber : int, ?first: string, ?last: string, ?bal : float) = + let mutable balance = defaultArg bal 0.0 + let mutable number = accountNumber + let mutable firstName = defaultArg first "" + let mutable lastName = defaultArg last "" + member this.AccountNumber + with get() = number + and set(value) = number <- value + member this.FirstName + with get() = firstName + and set(value) = firstName <- value + member this.LastName + with get() = lastName + and set(value) = lastName <- value + member this.Balance + with get() = balance + and set(value) = balance <- value + member this.Deposit(amount: float) = this.Balance <- this.Balance + amount + member this.Withdraw(amount: float) = this.Balance <- this.Balance - amount + + +let account2 = new Account2(8782108, bal = 543.33, + FirstName="Raman", LastName="Iyer") + + + +// Constructors and Inheritance +type MyClassBase2(x: int) = + let mutable z = x * x + do for i in 1..z do printf "%d " i + + +type MyClassDerived2(y: int) = + inherit MyClassBase2(y * 2) + do for i in 1..y do printf "%d " i + + +// In the case of multiple constructors, the following code can be used. +// The first line of the derived class constructors is the inherit clause, +// and the fields appear as explicit fields that are declared with the val keyword. +// For more information, see Explicit Fields: The val Keyword.+ +type BaseClass = + val string1 : string + new (str) = { string1 = str } + new () = { string1 = "" } + +type DerivedClass = + inherit BaseClass + + val string2 : string + new (str1, str2) = { inherit BaseClass(str1); string2 = str2 } + new (str2) = { inherit BaseClass(); string2 = str2 } + +let obj1 = DerivedClass("A", "B") +let obj2 = DerivedClass("A") diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Customers.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Customers.fs new file mode 100644 index 00000000..6f238cf7 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Customers.fs @@ -0,0 +1,13 @@ +module Customers + + +// Another way of implementing interfaces is to use object expressions. +type ICustomer = + abstract Name : string + abstract Age : int + +let createCustomer name age = + { new ICustomer with + member __.Name = name + member __.Age = age } + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Delegates.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Delegates.fs new file mode 100644 index 00000000..9dd69796 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Delegates.fs @@ -0,0 +1,119 @@ +module Delegates + +// The following code shows the syntax for creating delegates that represent various methods in a class. +// Depending on whether the method is a static method or an instance method, +// and whether it has arguments in the tuple form or the curried form, +// the syntax for declaring and assigning the delegate is a little different. + +type Test1() = + static member add(a : int, b : int) = + a + b + static member add2 (a : int) (b : int) = + a + b + + member x.Add(a : int, b : int) = + a + b + member x.Add2 (a : int) (b : int) = + a + b + +let replicate n c = String.replicate n (string c) + + +// Delegate specifications must not be curried types. +// Use 'typ * ... * typ -> typ' for multi-argument delegates, +// and 'typ -> (typ -> typ)' for delegates returning function values. + +type Delegate1 = delegate of (int * int) -> int// Delegate1 works with tuple arguments. +type Delegate2 = delegate of int * int -> int // Delegate2 works with curried arguments. +type Delegate3 = delegate of int * char -> string +type Delegate4 = delegate of int -> (int -> char) +type Delegate5 = delegate of int -> (int -> char -> string) +type Delegate6 = delegate of (int -> float) -> char +type Delegate7 = delegate of (int -> char -> string) -> float +type Delegate8 = delegate of int -> char +type Delegate9 = delegate of (int * int) -> char +type Delegate10 = delegate of int * int -> char +type Delegate11 = delegate of char -> unit +type Delegate12 = delegate of unit -> char +type Delegate13 = delegate of (int -> char -> string -> decimal) -> float + + +let function1(i : int, i2 : int) = 1 +let function2(i : int) (ch : int) = 1 +let function3(i : int) (s : char) = "" +let function4(i : int) (ch : int) = ' ' +let function5(i : int) (i2 : int) (ch : char) = "" +let function6(intIntFunction : int -> float) = ' ' +let function7(intCharStringFunction : int -> char -> string) = 0.5 +let function8(i : int) = ' ' +let function9(i : (int * int)) = ' ' +let function10(i : int) (i2 : int) = ' ' +let function11(c : char) = () +let function12(c : unit) = ' ' +let function12_1() = ' ' +let function13(intCharStringDecimalFunction : int -> char -> string -> decimal) = 0.5 + +let delObject1 = new Delegate1(function1) +let delObject2 = new Delegate2(function2) +let delObject3 = new Delegate3(function3) +let delObject4 = new Delegate4(function4) +let delObject5 = new Delegate5(function5) +let delObject6 = new Delegate6(function6) +let delObject7 = new Delegate7(function7) +let delObject8 = new Delegate8(function8) +let delObject9 = new Delegate9(function9) +let delObject10 = new Delegate10(function10) +let delObject11 = new Delegate11(function11) +let delObject12 = new Delegate12(function12) +let delObject12_1 = new Delegate12(function12_1) +let delObject13 = new Delegate13(function13) + + + + + +let InvokeDelegate1 (dlg : Delegate1) (a : int) (b: int) = + dlg.Invoke(a, b) +let InvokeDelegate2 (dlg : Delegate2) (a : int) (b: int) = + dlg.Invoke(a, b) + +// For static methods, use the class name, the dot operator, and the +// name of the static method. +let del1 : Delegate1 = new Delegate1( Test1.add ) +let del2 : Delegate2 = new Delegate2( Test1.add2 ) + +let testObject = Test1() + +// For instance methods, use the instance value name, the dot operator, and the instance method name. +let del3 : Delegate1 = new Delegate1( testObject.Add ) +let del4 : Delegate2 = new Delegate2( testObject.Add2 ) + +for (a, b) in [ (100, 200); (10, 20) ] do + printfn "%d + %d = %d" a b (InvokeDelegate1 del1 a b) + printfn "%d + %d = %d" a b (InvokeDelegate2 del2 a b) + printfn "%d + %d = %d" a b (InvokeDelegate1 del3 a b) + printfn "%d + %d = %d" a b (InvokeDelegate2 del4 a b) + +// The following code shows some of the different ways you can work with delegates. + + +// An F# function value constructed from an unapplied let-bound function +let function1_ = replicate + +// A delegate object constructed from an F# function value +let delObject = new Delegate3(function1_) + +// An F# function value constructed from an unapplied .NET member +let functionValue = delObject.Invoke + +List.map (fun c -> functionValue(5,c)) ['a'; 'b'; 'c'] +|> List.iter (printfn "%s") + +// Or if you want to get back the same curried signature +let replicate' n c = delObject.Invoke(n,c) + +// You can pass a lambda expression as an argument to a function expecting a compatible delegate type +// System.Array.ConvertAll takes an array and a converter delegate that transforms an element from +// one type to another according to a specified function. +let stringArray = System.Array.ConvertAll([|'a';'b'|], fun c -> replicate' 3 c) +printfn "%A" stringArray diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/DiscriminatedUnions.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/DiscriminatedUnions.fs new file mode 100644 index 00000000..fe6f8e63 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/DiscriminatedUnions.fs @@ -0,0 +1,18 @@ +module DiscriminatedUnions + +//The preceding code declares a discriminated union Shape, +// which can have values of any of three cases: Rectangle, Circle, and Prism. +// Each case has a different set of fields. +type Shape = + | Rectangle of width : float * length : float + | Circle of radius : float + | Prism of width : float * float * height : float + +let rect = Rectangle(length = 1.3, width = 10.0) +let circ = Circle (1.0) +let prism = Prism(5., 2.0, height = 3.0) + + +type SizeUnion = Small | Medium | Large // union +type ColorEnum = Red=5 | Yellow=7 | Blue=9 // enum + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/DoBindings.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/DoBindings.fs new file mode 100644 index 00000000..8da284e8 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/DoBindings.fs @@ -0,0 +1,16 @@ +module DoBindings + +open System + +type MyBindingType(a:int, b:int) as this = + inherit Object() + let x = 2*a + let y = 2*b + do printfn "Initializing object %d %d %d %d %d %d" + a b x y (this.Prop1) (this.Prop2) + static do printfn "Initializing MyBindingType." + member this.Prop1 = 4*x + member this.Prop2 = 4*y + override this.ToString() = System.String.Format("{0} {1}", this.Prop1, this.Prop2) + +let obj1 = new MyBindingType(1, 2)
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Enumerations.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Enumerations.fs new file mode 100644 index 00000000..5b5a8bb5 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Enumerations.fs @@ -0,0 +1,10 @@ +module Enumerations + +// Declaration of an enumeration. +type Color = + | Red = 0 + | Green = 1 + | Blue = 2 + +// Use of an enumeration. +let col1 : Color = Color.Red
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Extensions.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Extensions.fs new file mode 100644 index 00000000..cb5c52b6 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Extensions.fs @@ -0,0 +1,31 @@ +module Extensions + +module MyModule1 = + + // Define a type. + type MyClass() = + member this.F() = 100 + + // Define type extension. + type MyClass with + member this.G() = 200 + +module MyModule2 = + let function1 (obj1: MyModule1.MyClass) = + // Call an ordinary method. + printfn "%d" (obj1.F()) + // Call the extension method. + printfn "%d" (obj1.G()) + +// Define a new member method FromString on the type Int32. +type System.Int32 with + member this.FromString( s : string ) = + System.Int32.Parse(s) + +let testFromString str = + let mutable i = 0 + // Use the extension method. + i <- i.FromString(str) + printfn "%d" i + +testFromString "500"
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/FlexibleTypes.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/FlexibleTypes.fs new file mode 100644 index 00000000..0e06b9bf --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/FlexibleTypes.fs @@ -0,0 +1,10 @@ +module FlexibleTypes + +let iterate1 (f : unit -> seq<int>) = + for e in f() do printfn "%d" e +let iterate2 (f : unit -> #seq<int>) = + for e in f() do printfn "%d" e +let iterate3<'T when 'T :> seq<int>> (f : unit -> 'T) = () +let iterate4<'T when 'T :> Customers.ICustomer> (f : unit -> 'T) = () + + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Functions.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Functions.fs new file mode 100644 index 00000000..58c6ee6e --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Functions.fs @@ -0,0 +1,33 @@ +module Functions + +// You define functions by using the let keyword, or, if the function is recursive, the let rec keyword combination.+ +let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2) + +let rec public publicLet n = if n < 2 then 1 else fib (n - 1) + fib (n - 2) + +// Functions in F# can be composed from other functions. +// The composition of two functions function1 and function2 is another function that represents the application of function1 followed the application of function2: +let function1 x = x + 1 +let function2 x2 = x2 * 2 +let function3 (x3) = x3 * 2 +let function4 x4 y4 = x4 + y4 +let function5 (x5, y5) = x5 + y5 +let function6 (x6, y6) = () +let function7 x7 (y7, z7) = () +let function8 x8 y8 z8 = () +let function9 (x9, y9) (z9, a9) = () +let function10<'a> (x, y) (z, a) = () +let function11<'a> (x, y, z) (a, b) = () +let function12<'a> x (a, b, c, d, e) = () +let function13<'a> (a:'a) = () + +let h = function1 >> function2 +let result5 = h 100 + +//Pipelining enables function calls to be chained together as successive operations. Pipelining works as follows: +let result = 100 |> function1 |> function2 + +type TestFunction() = + member this.f13 : 'a -> unit = function13 + // member this.f13<'a> : 'a -> unit = function13 // Error FS0671 A property cannot have explicit type parameters. Consider using a method instead. +
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Generics.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Generics.fs new file mode 100644 index 00000000..c9a35b05 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Generics.fs @@ -0,0 +1,28 @@ +module Generics + +// In the following code example, makeList is generic, +// even though neither it nor its parameters are explicitly declared as generic. +let makeList a b = [a; b] + +// You can also make a function generic by using the single quotation mark syntax +// in a type annotation to indicate that a parameter type is a generic type parameter. +// In the following code, function1 is generic because its parameters are declared in this manner, as type parameters. +let function1 (x: 'a) (y: 'a) = + printfn "%A %A" x y + +// You can also make a function generic by explicitly +// declaring its type parameters in angle brackets (<type-parameter>) +let function2<'T> x y = + printfn "%A, %A" x y + + +type Map2<[<EqualityConditionalOn>]'Key,[<EqualityConditionalOn>][<ComparisonConditionalOn>]'Value when 'Key : comparison and 'Value : comparison> = class + //member this.Item ('Key) : 'Value (requires comparison) +// member Item : key:'Key -> 'Value with get + member this.fffff : option<int> = None + member this.l : list<int> = [ 1; 2; 3 ] + member this.c : Choice<int, float> = Choice1Of2 0 + member this.c2 : Choice<int, float> = Choice2Of2 0.5 + member this.r : ref<int> = ref 0 + member this.s : seq<int> = seq { for i in 1 .. 10 do yield i * i } +end diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/IndexedProperties.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/IndexedProperties.fs new file mode 100644 index 00000000..71660a10 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/IndexedProperties.fs @@ -0,0 +1,30 @@ +module IndexedProperties + +type NumberStrings() = + let mutable ordinals = [| "one"; "two"; "three"; "four"; "five"; + "six"; "seven"; "eight"; "nine"; "ten" |] + let mutable cardinals = [| "first"; "second"; "third"; "fourth"; + "fifth"; "sixth"; "seventh"; "eighth"; + "ninth"; "tenth" |] + member this.Item + with get(index) = ordinals.[index] + and set index value = ordinals.[index] <- value + member this.Ordinal + with get(index) = ordinals.[index] + and set index value = ordinals.[index] <- value + member this.Cardinal + with get(index) = cardinals.[index] + and set index value = cardinals.[index] <- value + +let nstrs = new NumberStrings() +nstrs.[0] <- "ONE" +for i in 0 .. 9 do + printf "%s " (nstrs.[i]) +printfn "" + +nstrs.Cardinal(5) <- "6th" + +for i in 0 .. 9 do + printf "%s " (nstrs.Ordinal(i)) + printf "%s " (nstrs.Cardinal(i)) +printfn ""
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Inheritance.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Inheritance.fs new file mode 100644 index 00000000..aade392d --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Inheritance.fs @@ -0,0 +1,45 @@ +module Inheritance + +//The following code example illustrates the declaration of +// a new virtual method function1 in a base class +// and how to override it in a derived class. +type MyClassBase1() = + let mutable z = 0 + abstract member function1 : int -> int + default u.function1(a : int) = z <- z + a; z + +type MyClassDerived1() = + inherit MyClassBase1() + override u.function1(a: int) = a + 1 + + +//The following code shows a base class and a derived class, +// where the derived class calls the base class constructor in the inherit clause:+ +type MyClassBase2(x: int) = + let mutable z = x * x + do for i in 1..z do printf "%d " i + +type MyClassDerived2(y: int) = + inherit MyClassBase2(y * 2) + do for i in 1..y do printf "%d " i + + + +//In the case of multiple constructors, the following code can be used. +// The first line of the derived class constructors is the inherit clause, +// and the fields appear as explicit fields that are declared with the val keyword. +// For more information, see Explicit Fields: The val Keyword. +type BaseClass = + val string1 : string + new (str) = { string1 = str } + new () = { string1 = "" } + +type DerivedClass = + inherit BaseClass + + val string2 : string + new (str1, str2) = { inherit BaseClass(str1); string2 = str2 } + new (str2) = { inherit BaseClass(); string2 = str2 } + +let obj1 = DerivedClass("A", "B") +let obj2 = DerivedClass("A")
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/InheritanceAlternative.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/InheritanceAlternative.fs new file mode 100644 index 00000000..28fd9f85 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/InheritanceAlternative.fs @@ -0,0 +1,13 @@ +module AlternativesToInheritance + +open System + +// In cases where a minor modification of a type is required, +// consider using an object expression as an alternative to inheritance. +// The following example illustrates the use of an object expression as an alternative +// to creating a new derived type: +let object1 = { new Object() with + override this.ToString() = "This overrides object.ToString()" + } + +printfn "%s" (object1.ToString())
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/InlineFunctions.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/InlineFunctions.fs new file mode 100644 index 00000000..8ccbf250 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/InlineFunctions.fs @@ -0,0 +1,16 @@ +module InlineFunctions + +// The following code example illustrates an inline function at the top level, +// an inline instance method, and an inline static method. + +let inline increment x = x + 1 +type WrapInt32() = + member inline this.incrementByOne(x) = x + 1 + static member inline Increment(x) = x + 1 + +// The presence of inline affects type inference. +// This is because inline functions can have statically resolved type parameters, +// whereas non-inline functions cannot. The following code example shows a case where inline +// is helpful because you are using a function that has a statically resolved type parameter, the float conversion operator. +let inline printAsFloatingPoint number = + printfn "%f" (float number) diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Interfaces.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Interfaces.fs new file mode 100644 index 00000000..3d279d76 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Interfaces.fs @@ -0,0 +1,52 @@ +module Interfaces + +// You can implement one or more interfaces in a class type by using the interface keyword, +// the name of the interface, and the with keyword, followed by the interface member definitions, +// as shown in the following code. +type IPrintable = + abstract member Print : unit -> unit + +type SomeClass1(x: int, y: float) = + interface IPrintable with + member this.Print() = printfn "%d %f" x y + + + +// To call the interface method when you have an object of type SomeClass, +// you must upcast the object to the interface type, as shown in the following code.+ +let x1 = new SomeClass1(1, 2.0) +(x1 :> IPrintable).Print() + + +// An alternative is to declare a method on the object that upcasts and calls the interface method, +// as in the following example. +type SomeClass2(x: int, y: float) = + member this.Print() = (this :> IPrintable).Print() + interface IPrintable with + member this.Print() = printfn "%d %f" x y + +let x2 = new SomeClass2(1, 2.0) +x2.Print() + +// Interface Inheritance +type Interface0 = interface + abstract member Method1 : int -> int +end + +// Interface Inheritance +type Interface1 = + abstract member Method1 : int -> int + +type Interface2 = + abstract member Method2 : int -> int + +type Interface3 = + inherit Interface1 + inherit Interface2 + abstract member Method3 : int -> int + +type MyClass() = + interface Interface3 with + member this.Method1(n) = 2 * n + member this.Method2(n) = n + 100 + member this.Method3(n) = n / 10
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Library1.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Library1.fs new file mode 100644 index 00000000..bea234e1 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Library1.fs @@ -0,0 +1,29 @@ +namespace mdoc.Test.FSharp + +type Class1() = + member this.X = "F#" + + member this.T = Functions.function6(1, "32") + +type ClassPipes() = + let cylinderVolume (radius : float) (length : float) : float = radius * length + let smallPipeRadius = 2.0 + let bigPipeRadius = 3.0 + + // These define functions that take the length as a remaining + // argument: + + let smallPipeVolume = cylinderVolume(smallPipeRadius) + let bigPipeVolume = cylinderVolume bigPipeRadius + + let length1 = 30.0 + let length2 = 40.0 + member this.smallPipeVol1 = smallPipeVolume length1 + member this.smallPipeVol2 = smallPipeVolume length2 + member this.bigPipeVol1 = bigPipeVolume length1 + member this.bigPipeVol2 = bigPipeVolume length2 + member this.ff = Quotations.Var.Global("", typedefof<ClassPipes>) + //member this.ff2 = Quotations.Var.Global "" typedefof<ClassPipes> + member this.ff3 = Array.blit + //member this.ff4 = Array.averageBy None None + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Literals.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Literals.fs new file mode 100644 index 00000000..afab6e32 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Literals.fs @@ -0,0 +1,27 @@ +module Literals + +[<Literal>] +let Literal1 = "a" + "b" + +[<Literal>] +let FileLocation = __SOURCE_DIRECTORY__ + "/" + __SOURCE_FILE__ + +[<Literal>] +let Literal2 = 1 ||| 64 + +[<Literal>] +let Literal3 = System.IO.FileAccess.Read ||| System.IO.FileAccess.Write + +let someSbyte = 86y + +let someByte = 86uy + +let someBigint = 9999999999999999999999999999I + +let public someDecimal = 0.7833M + +let public someChar = 'a' + +let public someString = "text\n" + + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Methods.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Methods.fs new file mode 100644 index 00000000..59fb8e6b --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Methods.fs @@ -0,0 +1,97 @@ +module Methods + +open mdoc.Test.FSharp +open Interfaces + +type SomeType(factor0: int) = + // The following example illustrates the definition and use of a non-abstract instance method. + let factor = factor0 + let mul x y = x * y + let function1 (x : int) (z9, a9) = (1, 1) + let function2 (a : int -> int, b : int) = (1, 1) + + member this.SomeMethod(a, b, c) = + (a + b + c) * factor + + member this.SomeOtherMethod(a, b, c) = + this.SomeMethod(a, b, c) * factor + + member this.SomeOtherMethod2 : int -> int * int -> int * int = function1 + member this.SomeOtherMethod3 : (int -> int) * int -> int * int = function2 + + // The following example illustrates the definition and use of static methods + static member SomeStaticMethod(a, b, c) = + (a + b + c) + + static member SomeOtherStaticMethod(a, b, c) = + SomeType.SomeStaticMethod(a, b, c) * 100 + + static member SomeOtherStaticMethod2 a b c = a + b + c + static member SomeOtherStaticMethod3 (a, b) c d = a + b + c + d + + + + member this.TestRefParam (i : int ref) = 10 + member this.Test () = SomeType.SomeOtherStaticMethod + member this.Test2 () = this.SomeMethod + + +// The following example illustrates an abstract method Rotate that has a default implementation, +// the equivalent of a .NET Framework virtual method. +type Ellipse(a0 : float, b0 : float, theta0 : float) = + let mutable axis1 = a0 + let mutable axis2 = b0 + let mutable rotAngle = theta0 + let i1 = SomeType.SomeOtherStaticMethod(1, 2, 3) + let i2 = SomeType.SomeOtherStaticMethod2 1 2 3 + let i3 = SomeType.SomeOtherStaticMethod3 (1, 2) 3 4 + + abstract member Rotate: float -> unit + default this.Rotate(delta : float) = rotAngle <- rotAngle + delta + +// The following example illustrates a derived class that overrides a base class method. In this case, the override changes the behavior so that the method does nothing. +type Circle(radius : float) = + inherit Ellipse(radius, radius, 0.0) + // Circles are invariant to rotation, so do nothing. + override this.Rotate(_) = () + +type RectangleXY(x1 : float, y1: float, x2: float, y2: float) = + // Field definitions. + let height = y2 - y1 + let width = x2 - x1 + let area = height * width + // Private functions. + static let maxFloat (x: float) (y: float) = + if x >= y then x else y + static let minFloat (x: float) (y: float) = + if x <= y then x else y + // Properties. + // Here, "this" is used as the self identifier, + // but it can be any identifier. + member this.X1 = x1 + member this.Y1 = y1 + member this.X2 = x2 + member this.Y2 = y2 + // A static method. + static member intersection(rect1 : RectangleXY, rect2 : RectangleXY) = + let x1 = maxFloat rect1.X1 rect2.X1 + let y1 = maxFloat rect1.Y1 rect2.Y1 + let x2 = minFloat rect1.X2 rect2.X2 + let y2 = minFloat rect1.Y2 rect2.Y2 + let result : RectangleXY option = + if ( x2 > x1 && y2 > y1) then + Some (RectangleXY(x1, y1, x2, y2)) + else + None + result + +// Test code. +let testIntersection = + let r1 = RectangleXY(10.0, 10.0, 20.0, 20.0) + let r2 = RectangleXY(15.0, 15.0, 25.0, 25.0) + let r3 : RectangleXY option = RectangleXY.intersection(r1, r2) + match r3 with + | Some(r3) -> printfn "Intersection rectangle: %f %f %f %f" r3.X1 r3.Y1 r3.X2 r3.Y2 + | None -> printfn "No intersection found." + +testIntersection
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Namespaces.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Namespaces.fs new file mode 100644 index 00000000..f59342a4 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Namespaces.fs @@ -0,0 +1,9 @@ +namespace Widgets + + +// The following example shows a code file that declares a namespace Widgets with a type and a module included in that namespace. +type MyWidget1 = + member this.WidgetName = "Widget1" + +module WidgetsModule = + let widgetName = "Widget2"
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/NestedModules.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/NestedModules.fs new file mode 100644 index 00000000..68b601f7 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/NestedModules.fs @@ -0,0 +1,13 @@ +module NestedModules + +// Modules can be nested. Inner modules must be indented as far as outer module declarations +// to indicate that they are inner modules, not new modules. +module Y = + let y = 1 + + [<AutoOpen>] + module Z = + let z = 5 + +module X = + let x = 2
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/NestedTypes.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/NestedTypes.fs new file mode 100644 index 00000000..f2958521 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/NestedTypes.fs @@ -0,0 +1,6 @@ +module NestedTypes + +//I suppose nested classes were not a core feature of the .NET object model +// and it was simply dropped to save the resources. There may be some technical difficulties +// (i.e. with visibility or with recursive type definitions), but I don't think that would be a major problem. + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/OperatorGlobalLevel.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/OperatorGlobalLevel.fs new file mode 100644 index 00000000..33b9f9a9 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/OperatorGlobalLevel.fs @@ -0,0 +1,9 @@ +module OperatorGlobalLevel + +// You can also define operators at the global level. +// The following code defines an operator +?. +let inline (+?) (x: int) (y: int) = x + 2*y + +let i = (+?) + +printf "%d" (10 +? 1)
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/OperatorsOverloading.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/OperatorsOverloading.fs new file mode 100644 index 00000000..f97564cd --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/OperatorsOverloading.fs @@ -0,0 +1,42 @@ +module OperatorsOverloading + +// The following code illustrates a vector class that has just two operators, one for unary minus +// and one for multiplication by a scalar. In the example, two overloads for scalar multiplication are needed +// because the operator must work regardless of the order in which the vector and scalar appear.+ +type Vector(x: float, y : float) = + member this.x = x + member this.y = y + static member (~-) (v : Vector) = + Vector(-1.0 * v.x, -1.0 * v.y) + static member (*) (v : Vector, a) = + Vector(a * v.x, a * v.y) + static member (^^^) (a, v: Vector) = + Vector(a * v.x, a * v.y) + static member (?<-) (a, v, b: Vector) = + Vector(a * b.x, a * b.y) + static member (|+-+) (a : int, v: Vector) = + Vector(0.0, 0.0) + static member ( ~~~ ) (v: Vector) = + Vector(0.0, 0.0) + static member ( + ) (v: Vector, v2: Vector) = + Vector(0.0, 0.0) + static member ( .. .. ) (start, step, finish) = + Vector(0.0, 0.0) + static member ( .. ) (start, finish) = + Vector(0.0, 0.0) + override this.ToString() = + this.x.ToString() + " " + this.y.ToString() + +let v1 = Vector(1.0, 2.0) +let v2 = v1 * 2.0 +let v4 = - v2 +let v5 = 1 |+-+ v2 +let v7 = ~~~ v4 + +printfn "%s" (v1.ToString()) +printfn "%s" (v2.ToString()) +printfn "%s" (v4.ToString()) + +let v9 : ('T2 -> 'T3) -> ('T1 -> 'T2) -> ('T1 -> 'T3) = Operators.(<<) +let v10 : ('T2 -> 'T3) -> ('T1 -> 'T2) -> ('T1 -> 'T3) = Operators.(<<) + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/PatternMatchingExamples.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/PatternMatchingExamples.fs new file mode 100644 index 00000000..0d78183f --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/PatternMatchingExamples.fs @@ -0,0 +1,235 @@ +module PatternMatching.PatternMatchingExamples + +// Patterns are rules for transforming input data. They are used throughout the F# language +// to compare data with a logical structure or structures, decompose data into constituent parts, +// or extract information from data in various ways.1 + + + +// Constant Patterns +// The following example demonstrates the use of literal patterns, and also uses a variable pattern and an OR pattern.+ +[<Literal>] +let Three = 3 + +let filter123 x = + match x with + // The following line contains literal patterns combined with an OR pattern. + | 1 | 2 | Three -> printfn "Found 1, 2, or 3!" + // The following line contains a variable pattern. + | var1 -> printfn "%d" var1 + +for x in 1..10 do filter123 x + +// Another example of a literal pattern is a pattern based on enumeration constants. +// You must specify the enumeration type name when you use enumeration constants. +type Color = + | Red = 0 + | Green = 1 + | Blue = 2 + +let printColorName (color:Color) = + match color with + | Color.Red -> printfn "Red" + | Color.Green -> printfn "Green" + | Color.Blue -> printfn "Blue" + | _ -> () + +printColorName Color.Red +printColorName Color.Green +printColorName Color.Blue + + + +// Identifier Patterns +// The option type is a discriminated union that has two cases, Some and None. One case (Some) has a value, +// but the other (None) is just a named case. Therefore, Some needs to have a variable for the value associated +// with the Some case, but None must appear by itself. In the following code, the variable var1 is given the value +// that is obtained by matching to the Some case. +let printOption (data : int option) = + match data with + | Some var1 -> printfn "%d" var1 + | None -> () + +// In the following example, the PersonName discriminated union contains a mixture of strings +// and characters that represent possible forms of names. The cases of the discriminated union are FirstOnly, +// LastOnly, and FirstLast. +type PersonName = + | FirstOnly of string + | LastOnly of string + | FirstLast of string * string + +let constructQuery personName = + match personName with + | FirstOnly(firstName) -> printf "May I call you %s?" firstName + | LastOnly(lastName) -> printf "Are you Mr. or Ms. %s?" lastName + | FirstLast(firstName, lastName) -> printf "Are you %s %s?" firstName lastName + +// For discriminated unions that have named fields, you use the equals sign (=) to extract the value of a named field. +// For example, consider a discriminated union with a declaration like the following.+ +type Shape = + | Rectangle of height : float * width : float + | Circle of radius : float + +// You can use the named fields in a pattern matching expression as follows. +let matchShape shape = + match shape with + | Rectangle(height = h) -> printfn "Rectangle with length %f" h + | Circle(r) -> printfn "Circle with radius %f" r + +// When you specify multiple fields, use the semicolon (;) as a separator.+ +let matchShape2 shape = + match shape with + | Rectangle(height = h; width = w) -> printfn "Rectangle with height %f and width %f" h w + | _ -> () + + + +// Variable Patterns +// The following example demonstrates a variable pattern within a tuple pattern.+ +let function1 x = + match x with + | (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2 + | (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2 + | (var1, var2) -> printfn "%d equals %d" var1 var2 + +function1 (1,2) +function1 (2, 1) +function1 (0, 0) + + + +// as Pattern +let (var1, var2) as tuple1 = (1, 2) +printfn "%d %d %A" var1 var2 tuple1 + +// OR Pattern +let detectZeroOR point = + match point with + | (0, 0) | (0, _) | (_, 0) -> printfn "Zero found." + | _ -> printfn "Both nonzero." +detectZeroOR (0, 0) +detectZeroOR (1, 0) +detectZeroOR (0, 10) +detectZeroOR (10, 15) + +// AND Pattern +let detectZeroAND point = + match point with + | (0, 0) -> printfn "Both values zero." + | (var1, var2) & (0, _) -> printfn "First value is 0 in (%d, %d)" var1 var2 + | (var1, var2) & (_, 0) -> printfn "Second value is 0 in (%d, %d)" var1 var2 + | _ -> printfn "Both nonzero." +detectZeroAND (0, 0) +detectZeroAND (1, 0) +detectZeroAND (0, 10) +detectZeroAND (10, 15) + +// Cons Pattern +let list1 = [ 1; 2; 3; 4 ] +// This example uses a cons pattern and a list pattern. +let rec printList l = + match l with + | head :: tail -> printf "%d " head; printList tail + | [] -> printfn "" + +printList list1 + +//List Pattern +// This example uses a list pattern. +let listLength list = + match list with + | [] -> 0 + | [ _ ] -> 1 + | [ _; _ ] -> 2 + | [ _; _; _ ] -> 3 + | _ -> List.length list + +printfn "%d" (listLength [ 1 ]) +printfn "%d" (listLength [ 1; 1 ]) +printfn "%d" (listLength [ 1; 1; 1; ]) +printfn "%d" (listLength [ ] ) + +// Array Pattern +// This example uses array patterns. +let vectorLength vec = + match vec with + | [| var1 |] -> var1 + | [| var1; var2 |] -> sqrt (var1*var1 + var2*var2) + | [| var1; var2; var3 |] -> sqrt (var1*var1 + var2*var2 + var3*var3) + | _ -> failwith "vectorLength called with an unsupported array size of %d." (vec.Length) + +printfn "%f" (vectorLength [| 1. |]) +printfn "%f" (vectorLength [| 1.; 1. |]) +printfn "%f" (vectorLength [| 1.; 1.; 1.; |]) +printfn "%f" (vectorLength [| |] ) + +// Parenthesized Pattern +let countValues list value = + let rec checkList list acc = + match list with + | (elem1 & head) :: tail when elem1 = value -> checkList tail (acc + 1) + | head :: tail -> checkList tail acc + | [] -> acc + checkList list 0 + +let result = countValues [ for x in -10..10 -> x*x - 4 ] 0 +printfn "%d" result + +let countValues2<'a when 'a : equality> : List<'a> -> 'a -> int = countValues + +// Tuple Pattern +let detectZeroTuple point = + match point with + | (0, 0) -> printfn "Both values zero." + | (0, var2) -> printfn "First value is 0 in (0, %d)" var2 + | (var1, 0) -> printfn "Second value is 0 in (%d, 0)" var1 + | _ -> printfn "Both nonzero." +detectZeroTuple (0, 0) +detectZeroTuple (1, 0) +detectZeroTuple (0, 10) +detectZeroTuple (10, 15) + +// Record Pattern +// This example uses a record pattern. + +type MyRecord = { Name: string; ID: int } + +let IsMatchByName record1 (name: string) = + match record1 with + | { MyRecord.Name = nameFound; MyRecord.ID = _; } when nameFound = name -> true + | _ -> false + +let recordX = { Name = "Parker"; ID = 10 } +let isMatched1 = IsMatchByName recordX "Parker" +let isMatched2 = IsMatchByName recordX "Hartono" + + +// Wildcard Pattern +//Patterns That Have Type Annotations +let detect1 x = + match x with + | 1 -> printfn "Found a 1!" + | (var1 : int) -> printfn "%d" var1 +detect1 0 +detect1 1 + + +// Type Test Pattern +// open System.Windows.Forms +// +// let RegisterControl(control:Control) = +// match control with +// | :? Button as button -> button.Text <- "Registered." +// | :? CheckBox as checkbox -> checkbox.Text <- "Registered." +// | _ -> () + +// Null Pattern +let ReadFromFile (reader : System.IO.StreamReader) = + match reader.ReadLine() with + | null -> printfn "\n"; false + | line -> printfn "%s" line; true + +let fs = System.IO.File.Open("..\..\Program.fs", System.IO.FileMode.Open) +let sr = new System.IO.StreamReader(fs) +while ReadFromFile(sr) = true do () +sr.Close()
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Properties.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Properties.fs new file mode 100644 index 00000000..912f417c --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Properties.fs @@ -0,0 +1,24 @@ +module Properties + +type MyPropertiesType() = + let mutable myInternalValue = 0 + + // A read-only property. + member this.MyReadOnlyProperty = myInternalValue + + // A write-only property. + member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value + + // A read-write property. + member this.MyReadWriteProperty + with get () = myInternalValue + and set (value) = myInternalValue <- value + +type MyPropertyClass2(property1 : int) = + member val Property1 = property1 + member val Property2 = "" with get, set + +type MyAutoPropertyClass() = + let random = new System.Random() + member val AutoProperty = random.Next() with get, set + member this.ExplicitProperty = random.Next()
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Records.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Records.fs new file mode 100644 index 00000000..6fda4288 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Records.fs @@ -0,0 +1,17 @@ +module Records + +type MyRecord = { + X: int; + Y: int; + Z: int + } + +let myRecord1 = { X = 1; Y = 2; Z = 3; } + +type Car = { + Make : string + Model : string + mutable Odometer : int + } +let myCar = { Make = "Fabrikam"; Model = "Coupe"; Odometer = 108112 } +myCar.Odometer <- myCar.Odometer + 21
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/ReferenceCells.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/ReferenceCells.fs new file mode 100644 index 00000000..c8807601 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/ReferenceCells.fs @@ -0,0 +1,10 @@ +module ReferenceCells + +// Declare a reference. +let refVar = ref 6 + +// Change the value referred to by the reference. +refVar := 50 + +// Dereference by using the ! operator. +printfn "%d" !refVar
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Script.fsx b/mdoc/mdoc.Test/mdoc.Test.FSharp/Script.fsx new file mode 100644 index 00000000..4d2a3730 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Script.fsx @@ -0,0 +1,8 @@ +// Learn more about F# at http://fsharp.org. See the 'F# Tutorial' project +// for more guidance on F# programming. + +#load "Library1.fs" +open mdoc.Test.FSharp + +// Define your library scripting code here + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Structures.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Structures.fs new file mode 100644 index 00000000..315249cf --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Structures.fs @@ -0,0 +1,36 @@ +module Structures + +type public StructureType = + struct + val x: float + end + +// or +[<StructAttribute>] +type public StructureType2 = + val x: float + + +// In Point3D, three immutable values are defined. +// x, y, and z will be initialized to 0.0. +type Point3D = + struct + val x: float + val y: float + val z: float + end + +// In Point2D, two immutable values are defined. +// Point2D has an explicit constructor. +// You can create zero-initialized instances of Point2D, or you can +// pass in arguments to initialize the values. +type Point2D = + struct + val X: float + val Y: float + new(x: float, y: float) = + { + X = x; + Y = y + } +end
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/TypeExtensions.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/TypeExtensions.fs new file mode 100644 index 00000000..1b2229fd --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/TypeExtensions.fs @@ -0,0 +1,65 @@ +module TypeExtensions + +module TypeExtensions1 = + + // Define a type. + type MyClass() = + member this.F() = 100 + + // Define type extension. + type MyClass with + member this.G() = 200 + +module TypeExtensions2 = + let function1 (obj1: TypeExtensions1.MyClass) = + // Call an ordinary method. + printfn "%d" (obj1.F()) + // Call the extension method. + printfn "%d" (obj1.G()) + + + + +// Define a new member method FromString on the type Int32. +type System.Int32 with + member this.FromString( s : string ) = + System.Int32.Parse(s) + +let testFromString str = + let mutable i = 0 + // Use the extension method. + i <- i.FromString(str) + printfn "%d" i + +testFromString "500" + + + + +// Generic Extension Methods +open System.Collections.Generic + +type IEnumerable<'T> with + /// Repeat each element of the sequence n times + member xs.RepeatElements(n: int) = + seq { for x in xs do for i in 1 .. n do yield x } + +//However, for a generic type, the type variable may not be constrained. +// You can now declare a C#-style extension member in F# to work around this limitation. +// When you combine this kind of declaration with the inline feature of F#, +// you can present generic algorithms as extension members. +// Consider the following declaration: +open System.Runtime.CompilerServices +[<Extension>] +type ExtraCSharpStyleExtensionMethodsInFSharp () = + [<Extension>] + static member inline Sum(xs: IEnumerable<'T>) = Seq.sum xs + +let listOfIntegers = [ 1 .. 100 ] +//let listOfBigIntegers = [ 1I to 100I ] +let listOfBigIntegers = [ 1I .. 100I ] +let sum1 = listOfIntegers.Sum() +let sum2 = listOfBigIntegers.Sum() +//In this code, the same generic arithmetic code is applied to lists of two types without overloading, +// by defining a single extension member.+ + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/UnitsOfMeasure.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/UnitsOfMeasure.fs new file mode 100644 index 00000000..d11dff0a --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/UnitsOfMeasure.fs @@ -0,0 +1,77 @@ +module UnitsOfMeasure + +// The previous syntax defines unit-name as a unit of measure. The optional part is used to define a new measure in terms of previously defined units. For example, the following line defines the measure cm (centimeter).+ +// Distance, cm +[<Measure>] type cm + +// The following line defines the measure ml (milliliter) as a cubic centimeter (cm^3). +// Volume, milliliters. +[<Measure>] type ml = cm^3 + + +// Mass, grams. +[<Measure>] type g +// Mass, kilograms. +[<Measure>] type kg +// Weight, pounds. +[<Measure>] type lb + +// Distance, meters. +[<Measure>] type m + +// Distance, inches. +[<Measure>] type inch +// Distance, feet +[<Measure>] type ft + +// Time, seconds. +[<Measure>] type s + +// Force, Newtons. +[<Measure>] type N = kg m / s + +// Pressure, bar. +[<Measure>] type bar +// Pressure, Pascals +[<Measure>] type Pa = N / m^2 + +// Volume, liters. +[<Measure>] type L + +// Define conversion constants. +let gramsPerKilogram : float<g kg^-1> = 1000.0<g/kg> +let cmPerMeter : float<cm/m> = 100.0<cm/m> +let cmPerInch : float<cm/inch> = 2.54<cm/inch> + +let mlPerCubicCentimeter : float<ml/cm^3> = 1.0<ml/cm^3> +let mlPerLiter : float<ml/L> = 1000.0<ml/L> + +// Define conversion functions. +let convertGramsToKilograms (x : float<g>) = x / gramsPerKilogram +let convertCentimetersToInches (x : float<cm>) = x / cmPerInch + + +// Using Generic Units +let genericSumUnits ( x : float<'u>) (y: float<'u>) = x + y + +let v1 = 3.1<m/s> +let v2 = 2.7<m/s> +let x1 = 1.2<m> +let t1 = 1.0<s> + +// OK: a function that has unit consistency checking. +let result1 = genericSumUnits v1 v2 +// Error reported: mismatched units. +// Uncomment to see error. +// let result2 = genericSumUnits v1 x1 + +// Creating Aggregate Types with Generic Units +// Define a vector together with a measure type parameter. +// Note the attribute applied to the type parameter. +type vector3D<[<Measure>] 'u> = { x : float<'u>; y : float<'u>; z : float<'u>} + +// Create instances that have two different measures. +// Create a position vector. +let xvec : vector3D<m> = { x = 0.0<m>; y = 0.0<m>; z = 0.0<m> } +// Create a velocity vector. +let v1vec : vector3D<m/s> = { x = 1.0<m/s>; y = -1.0<m/s>; z = 0.0<m/s> }
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/Vector.fs b/mdoc/mdoc.Test/mdoc.Test.FSharp/Vector.fs new file mode 100644 index 00000000..300ab454 --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/Vector.fs @@ -0,0 +1,35 @@ +module SomeNamespace.SomeModule + +// This example is a basic class with (1) local let bindings, (2) properties, (3) methods, and (4) static members. +type Vector(x : float, y : float) = + let mag = sqrt(x * x + y * y) // (1) + member this.X = x // (2) + member this.Y = y + member this.Mag = mag + member this.Scale(s) = // (3) + Vector(x * s, y * s) + static member (+) (a : Vector, b : Vector) = // (4) + Vector(a.X + b.X, a.Y + b.Y) + + +// Declare IVector interface and implement it in Vector'. +type IVector = + abstract Scale : float -> IVector + +type Vector'''(x, y) = + interface IVector with + member __.Scale(s) = + Vector'''(x * s, y * s) :> IVector + member __.X = x + member __.Y = y + + + +type Vector2(x, y) = + interface IVector with + member __.Scale(s) = + Vector2(x * s, y * s) :> IVector + member __.X = x + member __.Y = y + + diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/mdoc.Test.FSharp.fsproj b/mdoc/mdoc.Test/mdoc.Test.FSharp/mdoc.Test.FSharp.fsproj new file mode 100644 index 00000000..2d15173d --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/mdoc.Test.FSharp.fsproj @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>979f9f80-12fe-4236-9e93-6d554ab13701</ProjectGuid> + <OutputType>Library</OutputType> + <RootNamespace>mdoc.Test.FSharp</RootNamespace> + <AssemblyName>mdoc.Test.FSharp</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <TargetFSharpCoreVersion>4.4.1.0</TargetFSharpCoreVersion> + <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> + <Name>mdoc.Test.FSharp</Name> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <Tailcalls>false</Tailcalls> + <OutputPath>bin\$(Configuration)\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <WarningLevel>3</WarningLevel> + <DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <Tailcalls>true</Tailcalls> + <OutputPath>bin\$(Configuration)\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <WarningLevel>3</WarningLevel> + <DocumentationFile>bin\$(Configuration)\$(AssemblyName).XML</DocumentationFile> + </PropertyGroup> + <PropertyGroup> + <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion> + </PropertyGroup> + <Choose> + <When Condition="'$(VisualStudioVersion)' == '11.0'"> + <PropertyGroup Condition=" '$(FSharpTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets') "> + <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath> + </PropertyGroup> + </When> + <Otherwise> + <PropertyGroup Condition=" '$(FSharpTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets') "> + <FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath> + </PropertyGroup> + </Otherwise> + </Choose> + <Import Project="$(FSharpTargetsPath)" /> + <ItemGroup> + <Compile Include="AssemblyInfo.fs" /> + <None Include="Script.fsx" /> + <Content Include="packages.config" /> + <Compile Include="AbstractClasses.fs" /> + <Compile Include="Accessibility.fs" /> + <Compile Include="AccessibilityTest.fs" /> + <Compile Include="Animals.fs" /> + <Compile Include="Attributes.fs" /> + <Compile Include="ClassMembers.fs" /> + <Compile Include="Collections.fs" /> + <Compile Include="Constraints.fs" /> + <Compile Include="Constructors.fs" /> + <Compile Include="Customers.fs" /> + <Compile Include="Delegates.fs" /> + <Compile Include="DiscriminatedUnions.fs" /> + <Compile Include="DoBindings.fs" /> + <Compile Include="Enumerations.fs" /> + <Compile Include="Extensions.fs" /> + <Compile Include="FlexibleTypes.fs" /> + <Compile Include="Functions.fs" /> + <Compile Include="Generics.fs" /> + <Compile Include="IndexedProperties.fs" /> + <Compile Include="Inheritance.fs" /> + <Compile Include="InheritanceAlternative.fs" /> + <Compile Include="InlineFunctions.fs" /> + <Compile Include="Interfaces.fs" /> + <Compile Include="Literals.fs" /> + <Compile Include="Methods.fs" /> + <Compile Include="Namespaces.fs" /> + <Compile Include="NestedModules.fs" /> + <Compile Include="NestedTypes.fs" /> + <Compile Include="OperatorGlobalLevel.fs" /> + <Compile Include="OperatorsOverloading.fs" /> + <Compile Include="PatternMatchingExamples.fs" /> + <Compile Include="Properties.fs" /> + <Compile Include="Records.fs" /> + <Compile Include="ReferenceCells.fs" /> + <Compile Include="Structures.fs" /> + <Compile Include="TypeExtensions.fs" /> + <Compile Include="UnitsOfMeasure.fs" /> + <Compile Include="Vector.fs" /> + <Compile Include="Library1.fs" /> + </ItemGroup> + <ItemGroup> + <Reference Include="mscorlib" /> + <Reference Include="FSharp.Core"> + <Name>FSharp.Core</Name> + <AssemblyName>FSharp.Core.dll</AssemblyName> + <HintPath>$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Numerics" /> + <Reference Include="System.ValueTuple"> + <HintPath>..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll</HintPath> + </Reference> + </ItemGroup> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/mdoc/mdoc.Test/mdoc.Test.FSharp/packages.config b/mdoc/mdoc.Test/mdoc.Test.FSharp/packages.config new file mode 100644 index 00000000..9958f16f --- /dev/null +++ b/mdoc/mdoc.Test/mdoc.Test.FSharp/packages.config @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="System.ValueTuple" version="4.3.1" targetFramework="net461" /> +</packages>
\ No newline at end of file |