Od autora
1. Nadawanie wartości i komunikacja z użytkownikiem
1.1. Programowanie funkcyjne – informacje ogólne
1.2. Identyfikator wartości
1.3. Interaktywna konsola
2. Programowanie funkcyjne
2.1. Proste funkcje
2.2. Dopasowanie do wzorca – podstawy
2.3. Rekurencja i funkcje rekurencyjne
2.4. Funkcje wyższego rzędu
2.5. Łączenie operacji w potok za pomocą operatora |>
2.6. Kompozycja funkcji za pomocą operatorów >>
2.7. Funkcje anonimowe
2.8. Rekurencja ogonowa
Niezmienne struktury danych
Opcje
3.3.1. Odwracanie listy
3.3.2. Suma elementów listy
3.4. Sekwencje
3.5. Zbiory
Krotki
Listy
Programowanie imperatywne
4.1. Dane, których wartości można zmieniać
4.2. Kontrola sterowania przebiegiem programu, czyli podejmujemy decyzje oraz pętle
4.2.1. Instrukcja warunkowa .
4.2.2. Pętle .
4.2.2.1. Pętla for
4.2.2.2. Pętla while … do
4.2.2.3. Pętla sekwencyjna
4.3. Tablice
4.3.1. Tablice jednowymiarowe
4.3.2. Tablice dwuwymiarowe
4.4. Działania na macierzach
4.4.1. Dodawanie macierzy
4.4.2. Odejmowanie macierzy
4.4.3. Mnożenie macierzy
4.5. Tworzenie wycinków
5. Programowanie obiektowe
5.1. Klasa Osoba
5.2. Dziedziczenie
Bibliografia
Nie jest to do końca poprawne, ale… program się kompiluje!
W ramach ćwiczeń utrwalających wymagający czytelnicy mogą przepisać wszystkie listingi programów zawartych w tej książce do wspomnianej postaci, wykorzystując funkcję główną main() oraz punkt wejścia do programu [<EntryPoint>] (zob. Od Autora).
ZADANIE
1.2
Napisz program, który wyświetla na ekranie komputera wartość predefiniowanej stałej π = 3,14... Należy przyjąć format wyświetlania tej stałej z dokładnością do pięciu miejsc po przecinku.
Przykładowe rozwiązanie – listing 1.2
// Zadanie 1.2
open System
Console.WriteLine("Program wyświetla stałą pi z zadaną dokładnością.")
Console.WriteLine("Pi = {0:##.#####}.", Math.PI)
// Zatrzymanie konsoli
Console.WriteLine("Naciśnij dowolny klawisz.") Console.ReadKey(true) |> ignore
Linijki kodu w programie…
Console.WriteLine("Pi = {0:##.#####}.", Math.PI); …oznaczają, że do wyświetlenia na ekranie liczby π przeznaczono 7 pól, w tym 5 na część ułamkową {0:##.#####}. Klasa Math jest standardową klasą języka F#, umożliwiającą wykonanie różnych matematycznych obliczeń.
Nadawanie wartości i komunikacja z użytkownikiem
Rezultat działania programu można zobaczyć na rysunku 1.2.
Program wyświetla stałą pi z zadaną dokładnością. Pi = 3,14159.
Rysunek
1.2. Efekt działania programu Zadanie 1.2
Do wyprowadzania wyników na ekran monitora można również skorzystać z funkcji printf i printfn. Stosując łańcuchy formatujące w postaci…
ciąg_formatujący wartości formatowane
…możemy otrzymać wyniki w wygodnej dla nas formie. Pokazuje to następujący fragment programu…
let pi = Math.PI
printfn "%f" pi
printfn "%1.1f" pi
printfn "%2.2f" pi
printfn "%2.8f" pi
…oraz rezultat jego działania:
3.141593
3.1 3.14 3.14159265
Więcej informacji na ten temat Czytelnik może znaleźć w publikacji [1] lub w Core.Printf Module (F#)7 na stronie internetowej https:// msdn.microsoft.com/en-us/.
7 Więcej na ten temat zob. Core.Printf Module (F#), https://msdn.microsoft.com/visualfsharpdocs/conceptual/core.printf-module-%5bfsharp%5d (dostęp: 18.05.2019).
Identyfik ator wartości
ROZDZIAŁ
Niezmienne struktury danych
W tym rozdziale przedstawię typowe zadania dotyczące struktur danych w języku F# wraz z przykładowymi rozwiązaniami.
Struktury danych pomagają programistom w grupowaniu i reprezentowaniu powiązanych wartości w użyteczne, logiczne jednostki. Język programowania F# ma bardzo dużo wbudowanych niezmiennych struktur danych, które m.in. zawierają:
• typ opcji (option type);
• krotki (tuples);
• listy (lists);
• sekwencje (sequences);
• zbiory i mapy (sets and maps);
• rekordy (records), unie i wiele innych.
Niektóre z nich (typ opcji, krotki, listy, sekwencje oraz zbiory) omówiono w przykładowych zadaniach w tym rozdziale.
3.1 Opcje
W języku F# typ opcji (option type) może przyjmować dwie wartości: albo jakąś wartość (oznaczoną jako Some), albo jej brak (oznaczoną
Niezmienne struktury danych
jako None). Opcje są bardzo wygodne, np. do zwracania wartości wyszukiwania, gdy wyniki mogą być dostępne, ale nie jest to pewne.
Oto przykład programu, w którym zastosowano bezpieczne dzielenie, aby uniknąć dzielenia przez zero.
ZADANIE 3.1
Napisz program, w którym zastosowano przykład bezpiecznego dzielenia, wykorzystujący typ Option.
Przykładowe rozwiązanie – listing 3.1
// Zadanie 3.1
open System
let bezp_dzielenie (x, y) = // Funkcja bezp_dzielenie "obsługuje" dzielenie przez 0 match y with | 0 -> None | _ -> Some (x/y)
let wynik = bezp_dzielenie(6, 2) // Próba normalnego dzielenia
let wynik1 = bezp_dzielenie(6, 0) // Próba dzielenia przez 0
if Option.isSome wynik then Console.WriteLine("Wynik dzielenia = {0}.", bezp_dzielenie(6, 2)) if Option.isNone wynik1 then Console.WriteLine("Uwaga: próba dzielenia przez 0.")
// Zatrzymanie konsoli
Console.WriteLine("Naciśnij dowolny klawisz.")
Console.ReadKey(true) |> ignore
W programie do wykonywania operacji z użyciem opcji skorzystaliśmy z właściwości modułu Option.
4.4.2
Odejmowanie macierzy
ZADANIE 4.28
Dane są dwie macierze o nazwach a i b. Ich postać jest taka sama jak w zadaniu 4.27. Napisz program, który oblicza różnicę tych macierzy i który na ekranie komputera wyświetla wynik odejmowania c = a - b.
Przykładowe rozwiązanie – listing 4.28
// Zadanie 4.28
open System
let mutable wymiar = 10 // Wymiar tablicy
let a = Array2D.create wymiar wymiar 2 // Utworzenie
tablicy a 2D wymiar x wymiar i wypełnienie jej 2
let b = Array2D.create wymiar wymiar 1 // Utworzenie
tablicy b 2D wymiar x wymiar i wypełnienie jej 1
let c = Array2D.create wymiar wymiar 0 // Utworzenie
tablicy c 2D wymiar x wymiar i wypełnienie jej 0
for i = 0 to wymiar - 1 do for j = 0 to wymiar - 1 do c.[i, j] <- a.[i, j] - b.[i, j] // Odejmowanie macierzy
printfn "Macierz a."
printfn "%A" a
printfn "Macierz b."
printfn "%A" b
printfn "Macierz c = a - b"
printfn "%A" c
// Zatrzymanie konsoli
Console.WriteLine("Naciśnij dowolny klawisz.")
Console.ReadKey(true) |> ignore
Rezultat działania programu można zobaczyć na rysunku 4.22.
Macierz a.
[[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]
[2; 2; 2; 2; 2; 2; 2; 2; 2; 2]]
Macierz b.
[[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]]
Macierz c = a - b
[[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]
[1; 1; 1; 1; 1; 1; 1; 1; 1; 1]]
Rysunek 4.22. Efekt działania programu Zadanie 4.28