Haskell - Podstawowe modele danych
Haskell jest czysto funkcjonalnym językiem programowania, dlatego jest znacznie bardziej interaktywny i inteligentny niż inne języki programowania. W tym rozdziale poznamy podstawowe modele danych Haskella, które są w rzeczywistości wstępnie zdefiniowane lub w jakiś inteligentny sposób dekodowane do pamięci komputera.
W tym samouczku będziemy korzystać z platformy internetowej Haskell dostępnej na naszej stronie internetowej (https://www.tutorialspoint.com/codingground.htm).
Liczby
Haskell jest na tyle inteligentny, aby rozszyfrować jakąś liczbę jako liczbę. Dlatego nie musisz wymieniać jego typu na zewnątrz, jak to zwykle robimy w przypadku innych języków programowania. Jak na przykład, przejdź do wiersza poleceń preludium i po prostu uruchom "2 + 2" i naciśnij Enter.
sh-4.3$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 2+2
W rezultacie otrzymasz następujące dane wyjściowe.
4
W powyższym kodzie właśnie przekazaliśmy dwie liczby jako argumenty do kompilatora GHCI bez uprzedniego zdefiniowania ich typu, ale kompilator mógł łatwo zdekodować te dwa wpisy jako liczby.
Spróbujmy teraz trochę bardziej skomplikowanych obliczeń matematycznych i zobaczmy, czy nasz inteligentny kompilator daje nam prawidłowe wyniki, czy nie. Spróbuj z „15+ (5 * 5) -40”
Prelude> 15+(5*5)-40
Powyższe wyrażenie daje „0” zgodnie z oczekiwanym wynikiem.
0
Postacie
Podobnie jak liczby, Haskell może inteligentnie zidentyfikować znak podany jako wejście do niego. Przejdź do wiersza poleceń Haskell i wpisz dowolny znak z podwójnym lub pojedynczym cudzysłowem.
Podajmy następujący wiersz jako wejście i sprawdźmy jego wyjście.
Prelude> :t "a"
Wytworzy następujący wynik -
"a" :: [Char]
Pamiętaj, że używasz (:t) podczas zasilania wejścia. W powyższym przykładzie(:t)polega na uwzględnieniu określonego typu związanego z danymi wejściowymi. Więcej o tym typie dowiemy się w kolejnych rozdziałach.
Spójrz na poniższy przykład, w którym przekazujemy nieprawidłowe dane wejściowe jako znak, co z kolei prowadzi do błędu.
Prelude> :t a
<interactive>:1:1: Not in scope: 'a'
Prelude> a
<interactive>:4:1: Not in scope: 'a'
Komunikatem o błędzie „<interactive>: 4: 1: Poza zakresem:„ a ”” kompilator Haskell ostrzega nas, że nie jest w stanie rozpoznać wprowadzonych danych. Haskell to rodzaj języka, w którym wszystko jest reprezentowane za pomocą liczby.
Haskell stosuje konwencjonalny styl kodowania ASCII. Spójrzmy na następujący przykład, aby zrozumieć więcej -
Prelude> '\97'
'a'
Prelude> '\67'
'C'
Zobacz, jak twoje dane wejściowe są dekodowane do formatu ASCII.
Strunowy
ZA stringto nic innego jak zbiór znaków. Nie ma określonej składni do używania łańcucha, ale Haskell stosuje konwencjonalny styl przedstawiania ciągu w podwójnym cudzysłowie.
Spójrz na poniższy przykład, w którym przekazujemy ciąg „Tutorialspoint.com”.
Prelude> :t "tutorialspoint.com"
Na ekranie wyświetli się następujący wynik -
"tutorialspoint.com" :: [Char]
Zobacz, jak cały ciąg został zdekodowany jako tablica tylko znaków Char. Przejdźmy do innego typu danych i jego składni. Gdy zaczniemy naszą rzeczywistą praktykę, przyzwyczaimy się do wszystkich typów danych i ich wykorzystania.
Boolean
Typ danych Boolean jest również dość prosty, podobnie jak inne typy danych. Spójrz na poniższy przykład, w którym użyjemy różnych operacji boolowskich przy użyciu niektórych danych wejściowych typu Boolean, takich jak „True” lub „False”.
Prelude> True && True
True
Prelude> True && False
False
Prelude> True || True
True
Prelude> True || False
True
W powyższym przykładzie nie musimy wspominać, że „True” i „False” to wartości boolowskie. Sam Haskell może go zdekodować i wykonać odpowiednie operacje. Zmodyfikujmy nasze dane wejściowe za pomocą „true” lub „false”.
Prelude> true
Wytworzy następujący wynik -
<interactive>:9:1: Not in scope: 'true'
W powyższym przykładzie Haskell nie mógł odróżnić „prawda” od wartości liczbowej, stąd nasze dane wejściowe „prawda” nie są liczbą. Dlatego kompilator Haskell zgłasza błąd informujący, że nasze dane wejściowe nie są jego zakresem.
Rozumienie listy i listy
Podobnie jak inne typy danych, Listjest również bardzo użytecznym typem danych używanym w Haskell. Na przykład [a, b, c] jest listą znaków, stąd z definicji Lista jest zbiorem danych tego samego typu, oddzielonych przecinkami.
Podobnie jak w przypadku innych typów danych, nie musisz deklarować listy jako listy. Haskell jest wystarczająco inteligentny, aby zdekodować twoje dane wejściowe, patrząc na składnię używaną w wyrażeniu.
Spójrz na poniższy przykład, który pokazuje, jak Haskell traktuje listę.
Prelude> [1,2,3,4,5]
Wytworzy następujący wynik -
[1,2,3,4,5]
Listy w Haskell są z natury jednorodne, co oznacza, że nie pozwalają na deklarowanie listy różnego rodzaju danych. Każda lista taka jak [1, 2, 3, 4, 5, a, b, c, d, e, f] spowoduje błąd.
Prelude> [1,2,3,4,5,a,b,c,d,e,f]
Ten kod spowoduje następujący błąd -
<interactive>:17:12: Not in scope: 'a'
<interactive>:17:14: Not in scope: 'b'
<interactive>:17:16: Not in scope: 'c'
<interactive>:17:18: Not in scope: 'd'
<interactive>:17:20: Not in scope: 'e'
<interactive>:17:22: Not in scope: 'f'
Rozumienie listy
Zrozumienie listy to proces tworzenia listy przy użyciu wyrażeń matematycznych. Spójrz na poniższy przykład, w którym tworzymy listę przy użyciu wyrażenia matematycznego w formacie [wyjście | zakres, stan].
Prelude> [x*2| x<-[1..10]]
[2,4,6,8,10,12,14,16,18,20]
Prelude> [x*2| x<-[1..5]]
[2,4,6,8,10]
Prelude> [x| x<-[1..5]]
[1,2,3,4,5]
Ta metoda tworzenia jednej listy przy użyciu wyrażenia matematycznego nosi nazwę List Comprehension.
Tuple
Haskell zapewnia inny sposób deklarowania wielu wartości w jednym typie danych. Jest znany jakoTuple. Krotka może być traktowana jako lista, jednak istnieją pewne techniczne różnice między krotką a listą.
Krotka jest niezmiennym typem danych, ponieważ nie możemy modyfikować liczby elementów w czasie wykonywania, podczas gdy lista jest zmiennym typem danych.
Z drugiej strony Lista jest jednorodnym typem danych, ale krotka jest z natury niejednorodna, ponieważ krotka może zawierać różne typy danych.
Krotki są reprezentowane przez pojedynczy nawias. Spójrz na poniższy przykład, aby zobaczyć, jak Haskell traktuje krotkę.
Prelude> (1,1,'a')
Wytworzy następujący wynik -
(1,1,'a')
W powyższym przykładzie użyliśmy jednej krotki z dwoma number zmienne typu, a char zmienna typu.