Daily Archives: 16/05/2020

Haskell – Kiểu dữ liệu

Trong phần này chúng ta sẽ tìm hiểu các kiểu dữ liệu có trong Haskell.

Khai báo kiểu

Đầu tiên chúng ta phải biết cách khai báo kiểu dữ liệu cho một biến đã. Cú pháp khai báo là:

<tên_biến> :: <tên_kiểu>

Ví dụ:

main :: IO()
a :: Int
b :: Bool
main = return()

Các kiểu cơ bản

Haskell cũng có một số kiểu như trong các ngôn ngữ khác.

Bool

Mang giá trị đúng / sai (True / False). Ví dụ:

main :: IO()

a :: Bool
a = False

b :: Bool 
b = True

main = return()

Int

Đây là kiểu dữ liệu lưu trữ số nguyên có dấu, miền giá trị từ [-229, 229-1].

main :: IO()

i :: Int
i = 2020

j :: Int
j = -99999999
main = return()

Integer

Đây cũng là kiểu dữ liệu lưu trữ số nguyên, nhưng có thể lưu những con số rất lớn, thậm chí có thể dùng hết bộ nhớ trong máy để lưu.

main :: IO()
bi :: Integer
bi = 94919521698492921921919551295194198981621984623...
main = return()

Char

Đây là kiểu dữ liệu lưu trữ kí tự. Ví dụ:

main :: IO()
c :: Char
c = 'a'
main = return()

Lưu ý là chúng ta chỉ có thể bọc các kí tự trong cặp dấu nháy đơn ', không phải cặp dấu nháy kép ".

String

Cũng lưu trữ kí tự nhưng là một chuỗi nhiều kí tự.

main :: IO()
c :: String
c = "Phocode - Haskell"
main = return()

Khác với Char, chúng ta phải bọc các chuỗi String trong cặp dấu nháy đôi ".

Float/Double

Đây là kiểu dữ liệu lưu trữ số thập phân, điểm khác biệt là Float chỉ lưu 32 bit còn Double là 64 bit. (Tuy nhiên có nguồn cho biết trong các phiên bản Haskell hiện đại, cả Float và Double đều dùng 64 bit để lưu trữ).

main :: IO()

f :: Float
f = 3.1415

d :: Double
d = 9.9999999999

main = return()

List

Đây là kiểu danh sách. Cũng giống như mảng trong C++ hay Java, list trong Haskell chỉ lưu những phần tử có chung kiểu. Để khai báo một list thì chúng ta dùng cú pháp [tên_kiểu], ví dụ:

main :: IO()
list :: [Int]  -- List số nguyên
list = [1, 2, 3, 4, 5]
main = return()

Tuple

Nếu bạn đã từng lập trình Python thì bạn sẽ quen với kiểu tuple này, chúng ta có thể coi nó đơn giản như là một list nhưng có thể lưu nhiều phần tử với nhiều kiểu dữ liệu khác nhau. Để khai báo tuple thì chúng ta dùng cú pháp (tên_kiểu_1, tên_kiểu_2,.... tên_kiểu_n), khác với list là chúng ta khai báo bao nhiêu kiểu trong tuple thì phải gán chính xác bấy nhiêu phần tử, ví dụ:

main :: IO()
list :: (Int, Int, String)
list = (16, 5, "phocode.com")
-- list = ('a', 5, "Hello") --- Sai vì phần tử đầu tiên sai kiểu
-- list = (1, 2, "Hello", 4, 5) -- Lỗi vì số phần tử là 5 trong khi khai báo chỉ có 3
main = return()

Haskell có thể gán kiểu động

Để linh hoạt hơn trong khai báo biến, chúng ta có thể không cần dùng câu lệnh khai báo kiểu dữ liệu (bằng 2 dấu ::), mà cứ gán dữ liệu rồi Haskell sẽ tự động gán kiểu dữ liệu cho biến đó giùm chúng ta.

main :: IO()
num = 3 -- Int
char = 'a' -- Char
str = "Phocode" -- String
fl = 3.14 -- Float
main = return()

Biến trong Haskell là bất biến

Tức là không thể thay đổi giá trị của biến đó được.

main :: IO()
num = 3
num = 4 -- Lỗi Multiple declaration of 'num'
main = return()