//Rozdział 2.
//Perspektywa funkcyjna

//Podstawy funkcji

class Ops
{
    public static int Add(int a, int b)
    {
        return a + b;
    }
}

let add a b = a + b
[CompilationMapping]
public static class Program
{
    [CompilationArgumentCounts(new int[] {1, 1})]
    public static int add(int a, int b)
    {
        return a + b;
    }
}

let ac = add "abra" "kadabra"
printfn "%s" ac
 [CompilationArgumentCounts(new int[] {1, 1})]
public static string add(string a, string b)
{
    return a + b;
}
 let n = add 1 2

// Błąd: oczekiwano, że to wyrażenie będzie miało typ „string”, a tutaj jest typ „int”
Literały funkcyjne w języku C#
 BinaryOperation multiply = delegate (int a, int b)
{return a * b; }; 
int x = multiply (2, 3); // 6
 BinaryOperation multiply = (a, b) => {return a * b; };
 BinaryOperation multiply = (a, b) => a + b;
 Funkcje przechowywania w C#
 public delegate int BinaryOperation(int a, int b);
 BinaryOperation op = Ops.Add;
int x = op(2, 3);

class Program
{
    static int Subtract(int a, int b) => a - b;
    static void Main(string[] args)
    {
        BinaryOperation op = Subtract;
        int x = op(10, 2); // 8
    }
}

static void Main(string[] args)
{
    int Multiply(int a, int b) => a * b;
    BinaryOperation op = Multiply;
    int x = op(10, 2); // 20
}

void SomeMethod()
{
    BinaryOperation op = (a, b) => a / b;
    nt x = op(10, 2); // 5
}

Action doStuff = () => Console.WriteLine("wykonuję działania!");
doStuff(); // wyświetla "wykonuję działania!"
Action<string> printText = x => Console.WriteLine(x);
printText("hello"); // wyświetla "hello"

Func<int, int, int> mul = Multiply;
// lub 
Func<int, int, int> div = (a, b) => a / b;
 var div = (int a, int b) => a / b;
 Literały funkcyjne w języku F#
 let add a b = a + b
[<EntryPoint>]
let main argv =
    let z = add
    let result = z 1 2
    0
 let printValues a b =
    printf "a = %i; b = %i" a b
 let printValues a =
    let printValues@10-1 b =
        printf "a = %i; b = %i" a b
return printValues@10-1
 let add a b = a + b
 let addFive x = add 5 x
 let z = addFive 5 // z = 10

//Kompozycja

let addFive x = x + 5
let timesTwo x = x * 2

printfn "%i" (addFive (timesTwo 3)) // 11
printfn "%i" (3 |> timesTwo |> addFive)
printfn "%i" (addFive <| (timesTwo <| 3))
 let timesTwoAddFive x =
x |> timesTwo |> addFive
 let timesTwoAddFive = timesTwo >> addFive
printfn "%i" timesTwoAddFive 3 // 11

 
