Haskell - Dongthoigian https://dongthoigian.net/tag/haskell/ Khám phá những thủ thuật máy tính Mon, 12 Feb 2024 03:17:39 +0000 vi hourly 1 https://wordpress.org/?v=6.6.2 https://dongthoigian.net/wp-content/uploads/2021/07/cropped-logo-dongthoigian-32x32.png Haskell - Dongthoigian https://dongthoigian.net/tag/haskell/ 32 32 Haskell – Functor https://dongthoigian.net/haskell-functor/ https://dongthoigian.net/haskell-functor/#respond Sat, 28 May 2022 10:12:34 +0000 https://dongthoigian.net/?p=13872 Một functor là một lớp sẵn có với một định nghĩa chức năng như

The post Haskell – Functor appeared first on Dongthoigian.

]]>
Functor trong Haskell là một loại biểu diễn chức năng của các Loại khác nhau có thể được ánh xạ. Đây là một khái niệm cấp cao về việc triển khai tính đa hình. Theo các nhà phát triển Haskell, tất cả các Loại như Danh sách, Bản đồ, Cây, v.v. đều là thể hiện của Haskell Functor. Một functor là một lớp sẵn có với một định nghĩa chức năng như

class Functor f where 
   fmap :: (a -> b) -> f a -> f b 

Theo định nghĩa này, chúng ta có thể kết luận rằng Functor là một hàm nhận một hàm, chẳng hạn như, fmap () và trả về một hàm khác. Trong ví dụ trên, fmap () là một biểu diễn tổng quát của bản đồ hàm () . Trong ví dụ sau, chúng ta sẽ xem Haskell Functor hoạt động như thế nào.

main = do  
   print(map (subtract 1) [2,4,8,16])      
   print(fmap (subtract 1) [2,4,8,16])

Ở đây, chúng tôi đã sử dụng cả map () và fmap () trên một danh sách cho một phép toán trừ. Bạn có thể thấy rằng cả hai câu lệnh sẽ mang lại cùng một kết quả là danh sách chứa các phần tử [1,3,7,15].

Cả hai hàm được gọi là một hàm khác được gọi là subtract () để mang lại kết quả.

[1,3,7,15][1,3,7,15]

Sau đó, sự khác biệt giữa map và fmap là gì? Sự khác biệt nằm ở cách sử dụng của chúng. Functor cho phép chúng tôi triển khai thêm một số hàm chức năng trong các kiểu dữ liệu khác nhau, như “just” và “Nothing”.

main = do 
   print (fmap  (+7)(Just 10)) 
   print (fmap  (+7) Nothing)

Đoạn mã trên sẽ mang lại kết quả đầu ra sau trên thiết bị đầu cuối:

Just 17
Nothing

Functor ứng dụng

Một Functor Ứng dụng là một Functor bình thường với một số tính năng bổ sung được cung cấp bởi Lớp Loại Ứng dụng.

Sử dụng Functor, chúng tôi thường ánh xạ một hàm hiện có với một hàm khác được định nghĩa bên trong nó. Nhưng không có bất kỳ cách nào để ánh xạ một hàm được định nghĩa bên trong Functor với Functor khác. Đó là lý do tại sao chúng tôi có một cơ sở khác được gọi là Application Functor . Cơ sở ánh xạ này được thực hiện bởi lớp Loại ứng dụng được xác định trong mô-đun Điều khiển . Lớp này chỉ cung cấp cho chúng ta hai phương thức để làm việc: một là thuần túy và một là <*> . Sau đây là định nghĩa lớp của Ứng dụng Functor

class (Functor f) => Applicative f where   
   pure :: a -> f a   
   (<*>) :: f (a -> b) -> f a -> f b 

Theo cách triển khai, chúng ta có thể ánh xạ Functor khác bằng hai phương pháp: “Pure” và “<*>” . Phương thức “Pure” phải nhận một giá trị thuộc bất kỳ loại nào và nó sẽ luôn trả về một Functor Ứng dụng có giá trị đó.

Ví dụ sau đây cho thấy cách một Functor Ứng dụng hoạt động:

import Control.Applicative 

f1:: Int -> Int -> Int 
f1 x y = 2*x+y  
main = do  
   print(show $ f1 <$> (Just 1) <*> (Just 2) ) 

Ở đây, chúng ta đã triển khai các hàm ứng dụng trong lời gọi hàm của hàm f1 . Chương trình của chúng tôi sẽ mang lại kết quả sau.

"Just 4"

Monoids

Chúng ta đều biết Haskell định nghĩa mọi thứ dưới dạng các hàm. Trong các hàm, chúng ta có các tùy chọn để lấy đầu vào của mình làm đầu ra của hàm. Đây là những gì một Monoid là.

Một monoid là một tập hợp các chức năng và các nhà khai thác mà đầu ra không phụ thuộc vào đầu vào của nó. Hãy lấy một hàm (*) và một số nguyên (1). Bây giờ, bất kể đầu vào có thể là gì, đầu ra của nó sẽ chỉ giữ nguyên một con số. Nghĩa là, nếu bạn nhân một số với 1, bạn sẽ nhận được cùng một số.

Đây là định nghĩa Loại Class của monoid.

class Monoid m where  
   mempty :: m 
   mappend :: m -> m -> m  
   mconcat :: [m] -> m 
   mconcat = foldr mappend mempty 

Hãy xem ví dụ sau để hiểu việc sử dụng Monoid trong Haskell

multi:: Int->Int 
multi x = x * 1 
add :: Int->Int 
add x = x + 0 

main = do  
   print(multi 9)  
   print (add 7)

Mã của chúng tôi sẽ tạo ra kết quả sau: 9 7

Ở đây, hàm “multi” nhân đầu vào với “1”. Tương tự, hàm “add” thêm đầu vào bằng “0”. Trong cả hai trường hợp, đầu ra sẽ giống với đầu vào. Do đó, các hàm {(*), 1} và {(+), 0} là những ví dụ hoàn hảo về đơn chất.

Haskell – Đơn nguyên

Các đơn nguyên không là gì ngoài một loại Functor Ứng dụng với một số tính năng bổ sung. Nó là một lớp Loại điều chỉnh ba quy tắc cơ bản được gọi là quy tắc đơn nguyên .

Tất cả ba quy tắc này đều có thể áp dụng nghiêm ngặt cho một tuyên bố Monad như sau:

class Monad m where  
   return :: a -> m a 
   (>>=) :: m a -> (a -> m b) -> m b 
   (>>) :: m a -> m b -> m b 
   x >> y = x >>= \_ -> y 
   fail :: String -> m a  
   fail msg = error msg 

Ba luật cơ bản có thể áp dụng cho tuyên bố Monad là:

  • Luật Định danh Trái – Hàm trả về không thay đổi giá trị và nó không được thay đổi bất cứ điều gì trong Đơn nguyên. Nó có thể được biểu thị là “return> => mf = mf”.
  • Luật Nhận dạng Đúng – Hàm trả về không thay đổi giá trị và nó không được thay đổi bất cứ điều gì trong Đơn nguyên. Nó có thể được biểu thị là “mf> => return = mf”.
  • Tính liên kết – Theo luật này, cả Functors và cá thể Monad đều phải hoạt động theo cùng một cách. Nó có thể được biểu thị bằng toán học là “(f> ==> g)> => h = f> => (g> = h)”.

Hai luật đầu tiên lặp lại cùng một điểm, tức là, một trả về phải có hành vi nhận dạng ở cả hai phía của toán tử ràng buộc . Chúng tôi đã sử dụng rất nhiều Đơn nguyên trong các ví dụ trước đây của chúng tôi mà không nhận ra rằng chúng là Đơn nguyên. Hãy xem xét ví dụ sau, nơi chúng tôi đang sử dụng Đơn nguyên danh sách để tạo một danh sách cụ thể

main = do
   print([1..10] >>= (\x -> if odd x then [x*2] else []))

Mã này sẽ tạo ra kết quả sau: [2,6,10,14,18]

Haskell – Dây kéo

Các khóa kéo trong Haskell về cơ bản là các con trỏ trỏ đến một số vị trí cụ thể của cấu trúc dữ liệu chẳng hạn như cây .

Chúng ta hãy xem xét một cây có 5 phần tử [45,7,55,120,56] có thể được biểu diễn như một cây nhị phân hoàn hảo. Nếu tôi muốn cập nhật phần tử cuối cùng của danh sách này, thì tôi cần xem qua tất cả các phần tử để tiếp cận phần tử cuối cùng trước khi cập nhật nó. Bên phải?

Nhưng, điều gì sẽ xảy ra nếu chúng ta có thể xây dựng cây của mình theo cách mà một cây có N phần tử là tập hợp của [(N-1), N] . Sau đó, chúng ta không cần phải duyệt qua tất cả các phần tử (N-1) không mong muốn . Chúng tôi có thể cập nhật trực tiếp phần tử thứ N. Đây chính xác là khái niệm Zipper. Nó tập trung hoặc trỏ đến một vị trí cụ thể của một cây mà chúng ta có thể cập nhật giá trị đó mà không cần đi ngang qua toàn bộ cây. Trong ví dụ sau, chúng tôi đã triển khai khái niệm Zipper trong một danh sách. Theo cách tương tự, người ta có thể triển khai Zipper trong cấu trúc dữ liệu dạng cây hoặc tệp .

data List a = Empty | Cons a (List a) deriving (Show, Read, Eq, Ord)
type Zipper_List a = ([a],[a])    

go_Forward :: Zipper_List a -> Zipper_List a   
go_Forward (x:xs, bs) = (xs, x:bs)   
   
go_Back :: Zipper_List a -> Zipper_List a   
go_Back (xs, b:bs) = (b:xs, bs)    

main = do 
   let list_Ex = [1,2,3,4] 
   print(go_Forward (list_Ex,[]))       
   print(go_Back([4],[3,2,1]))

Khi bạn biên dịch và thực thi chương trình trên, nó sẽ tạo ra kết quả sau:

([2,3,4],[1])

([3,4],[2,1])

Ở đây chúng tôi đang tập trung vào một phần tử của toàn bộ chuỗi trong khi tiến lên hoặc trong khi lùi lại.

The post Haskell – Functor appeared first on Dongthoigian.

]]>
https://dongthoigian.net/haskell-functor/feed/ 0
Haskell – Thành phần chức năng https://dongthoigian.net/haskell-thanh-phan-chuc-nang/ https://dongthoigian.net/haskell-thanh-phan-chuc-nang/#respond Sat, 28 May 2022 09:57:51 +0000 https://dongthoigian.net/?p=13868 Để triển khai thành phần hàm trong Haskell. Hãy xem đoạn mã ví dụ sau

The post Haskell – Thành phần chức năng appeared first on Dongthoigian.

]]>
Thành phần chức năng là quá trình sử dụng đầu ra của một chức năng như một đầu vào của chức năng khác. Sẽ tốt hơn nếu chúng ta học toán học đằng sau cấu tạo . Trong toán học, thành phần được ký hiệu là f {g (x)} trong đó g () là một hàm và đầu ra của nó được sử dụng làm đầu vào của một hàm khác, nghĩa là f () .

Thành phần chức năng có thể được thực hiện bằng cách sử dụng hai chức năng bất kỳ, miễn là kiểu đầu ra của một chức năng phù hợp với kiểu đầu vào của chức năng thứ hai. Chúng tôi sử dụng toán tử dấu chấm (.) Để triển khai thành phần hàm trong Haskell. Hãy xem đoạn mã ví dụ sau. Ở đây, chúng tôi đã sử dụng thành phần hàm để tính toán xem một số đầu vào là chẵn hay lẻ

eveno :: Int -> Bool 
noto  :: Bool -> String 

eveno x = if x `rem` 2 == 0 
   then True 
else False 
noto x = if x == True 
   then "This is an even Number" 
else "This is an ODD number" 

main = do 
   putStrLn "Example of Haskell Function composition" 
   print ((noto.eveno)(16))

Ở đây, trong hàm chính , chúng ta đang gọi đồng thời hai hàm, noto và eveno . Đầu tiên, trình biên dịch sẽ gọi hàm “eveno ()” với 16 làm đối số. Sau đó, trình biên dịch sẽ sử dụng đầu ra của phương thức eveno làm đầu vào của phương thức noto () .

Đầu ra của nó sẽ như sau:

 Example of Haskell Function composition              

 “This is an even Number”

Vì chúng ta đang cung cấp số 16 làm đầu vào (là một số chẵn), hàm eveno () trả về true , trở thành đầu vào cho hàm noto () và trả về đầu ra: “Đây là một số chẵn”.

Haskell - Mô-đun

Nếu bạn đã làm việc trên Java, thì bạn sẽ biết cách tất cả các lớp được liên kết vào một thư mục được gọi là gói . Tương tự, Haskell có thể được coi là một tập hợp các mô-đun .

Haskell là một ngôn ngữ chức năng và mọi thứ được biểu thị dưới dạng một biểu thức, do đó một Mô-đun có thể được gọi là một tập hợp các loại chức năng tương tự hoặc có liên quan.

Bạn có thể nhập một chức năng từ một mô-đun này vào một mô-đun khác. Tất cả các câu lệnh “nhập” phải xuất hiện đầu tiên trước khi bạn bắt đầu xác định các hàm khác. Trong chương này, chúng ta sẽ tìm hiểu các tính năng khác nhau của các mô-đun Haskell.

Mô-đun danh sách

Danh sách cung cấp một số chức năng tuyệt vời để làm việc với dữ liệu kiểu danh sách . Khi bạn nhập mô-đun Danh sách, bạn có nhiều chức năng theo ý của mình. Trong ví dụ sau, chúng tôi đã sử dụng một số chức năng quan trọng có sẵn trong mô-đun Danh sách.

import Data.List  

main = do  
   putStrLn("Different methods of List Module") 
   print(intersperse '.' "Tutorialspoint.com") 
   print(intercalate " " ["Lets","Start","with","Haskell"]) 
   print(splitAt 7 "HaskellTutorial") 
   print (sort [8,5,3,2,1,6,4,2])

Ở đây, chúng ta có nhiều chức năng mà không cần xác định chúng. Đó là bởi vì các chức năng này có sẵn trong mô-đun Danh sách. Sau khi nhập mô-đun Danh sách, trình biên dịch Haskell làm cho tất cả các chức năng này khả dụng trong không gian tên chung. Do đó, chúng tôi có thể sử dụng các chức năng này. Mã của chúng tôi sẽ mang lại kết quả sau:

Different methods of List Module
"T.u.t.o.r.i.a.l.s.p.o.i.n.t...c.o.m"
"Lets Start with Haskell"
("Haskell","Tutorial")
[1,2,2,3,4,5,6,8]

Mô-đun Char

Các Char mô-đun có rất nhiều chức năng được xác định trước để làm việc với các loại nhân vật. Hãy xem khối mã sau:

import Data.Char 

main = do  
   putStrLn("Different methods of Char Module") 
   print(toUpper 'a') 
   print(words "Let us study tonight") 
   print(toLower 'A')

Ở đây, các chức năng toUpper và toLower đã được xác định bên trong mô-đun Char . Nó sẽ tạo ra kết quả sau:

Different methods of Char Module
'A'
["Let","us","study","tonight"]
'a'

Mô-đun bản đồ

Bản đồ là kiểu dữ liệu kiểu cặp giá trị gia tăng không được sắp xếp. Nó là một mô-đun được sử dụng rộng rãi với nhiều chức năng hữu ích. Ví dụ sau đây cho thấy cách bạn có thể sử dụng một chức năng được xác định trước có sẵn trong mô-đun Bản đồ.

import Data.Map (Map) 
import qualified Data.Map as Map  --required for GHCI  

myMap :: Integer -> Map Integer [Integer] 
myMap n = Map.fromList (map makePair [1..n]) 
   where makePair x = (x, [x])  

main = print(myMap 3)

Nó sẽ tạo ra kết quả sau:

fromList [(1,[1]),(2,[2]),(3,[3])]

Đặt mô-đun

Mô-đun Set có một số chức năng được xác định trước rất hữu ích để thao tác với dữ liệu toán học. Một tập hợp được thực hiện dưới dạng cây nhị phân, vì vậy tất cả các phần tử trong một tập hợp phải là duy nhất. Hãy xem đoạn mã ví dụ sau

import qualified Data.Set as Set   

text1 = "Hey buddy"   
text2 = "This tutorial is for Haskell"   

main = do  
   let set1 = Set.fromList text1   
       set2 = Set.fromList text2 
   print(set1) 
   print(set2)

Ở đây, chúng tôi đang sửa đổi một Chuỗi thành một Tập hợp. Nó sẽ tạo ra kết quả sau. Quan sát rằng tập hợp đầu ra không có sự lặp lại của các ký tự

fromList " Hbdeuy"
fromList " HTaefhiklorstu"

Hãy xem cách chúng ta có thể tạo một mô-đun tùy chỉnh có thể được gọi ở các chương trình khác. Để triển khai mô-đun tùy chỉnh này, chúng tôi sẽ tạo một tệp riêng có tên “custom.hs” cùng với “main.hs” của chúng tôi .

Hãy để chúng tôi tạo mô-đun tùy chỉnh và xác định một vài chức năng trong đó.custom.hs

module Custom ( 
   showEven, 
   showBoolean 
) where 

showEven:: Int-> Bool 
showEven x = do 

if x 'rem' 2 == 0 
   then True 
else False 
showBoolean :: Bool->Int 
showBoolean c = do 

if c == True 
   then 1 
else 0

Mô-đun tùy chỉnh của chúng tôi đã sẵn sàng. Bây giờ, chúng ta hãy nhập nó vào một chương trình.

main.hs

import Custom 

main = do 
   print(showEven 4) 
   print(showBoolean True)

Mã của chúng tôi sẽ tạo ra kết quả sau: True 1

Hàm showEven trả về giá trị True , vì “4” là số chẵn. Hàm showBoolean trả về “1” vì hàm Boolean mà chúng ta đã truyền vào hàm là “True”.

Haskell – Đầu vào & Đầu ra

Tất cả các ví dụ mà chúng ta đã thảo luận cho đến nay đều có bản chất tĩnh. Trong chương này, chúng ta sẽ học cách giao tiếp động với người dùng. Chúng ta sẽ học các kỹ thuật đầu vào và đầu ra khác nhau được sử dụng trong Haskell.

Tệp và Luồng

Cho đến nay, chúng tôi đã mã hóa cứng tất cả các đầu vào trong chính chương trình. Chúng tôi đã lấy đầu vào từ các biến tĩnh. Bây giờ, chúng ta hãy tìm hiểu cách đọc và ghi từ một tệp bên ngoài.

Hãy để chúng tôi tạo một tệp và đặt tên là “abc.txt”. Tiếp theo, nhập các dòng sau vào tệp văn bản này: “Chào mừng bạn đến với Tutorialspoint. Tại đây, bạn sẽ nhận được tài nguyên tốt nhất để học Haskell.”

Tiếp theo, chúng ta sẽ viết đoạn mã sau để hiển thị nội dung của tệp này trên bảng điều khiển. Ở đây, chúng ta đang sử dụng hàm readFile () để đọc một tệp cho đến khi nó tìm thấy một ký tự EOF.

main = do  
   let file = "abc.txt" 
   contents <- readFile file 
   putStrLn contents 

Đoạn mã trên sẽ đọc tệp “abc.txt” dưới dạng Chuỗi cho đến khi nó gặp bất kỳ ký tự Cuối tệp nào. Đoạn mã này sẽ tạo ra kết quả sau.

Welcome to Tutorialspoint
Here, you will get the best resource to learn Haskell.

Quan sát rằng bất cứ thứ gì nó đang in trên thiết bị đầu cuối đều được ghi trong tệp đó.

Đối số dòng lệnh

Haskell cũng cung cấp cơ sở để vận hành một tệp thông qua dấu nhắc lệnh. Hãy để chúng tôi quay lại thiết bị đầu cuối và nhập “ghci” . Sau đó, nhập nhóm lệnh sau:

let file = "abc.txt" 
writeFile file "I am just experimenting here." 
readFile file

Ở đây, chúng tôi đã tạo một tệp văn bản có tên “abc.txt”. Tiếp theo, chúng tôi đã chèn một câu lệnh trong tệp bằng lệnh writeFile . Cuối cùng, chúng ta đã sử dụng lệnh readFile để in nội dung của tệp trên bảng điều khiển. Mã của chúng tôi sẽ tạo ra kết quả sau:

I am just experimenting here.

Ngoại lệ

Một ngoại lệ có thể được coi là một lỗi trong mã. Đó là một tình huống mà trình biên dịch không nhận được đầu ra mong đợi trong thời gian chạy. Giống như bất kỳ ngôn ngữ lập trình tốt nào khác, Haskell cung cấp một cách để thực hiện xử lý ngoại lệ.

Nếu bạn đã quen thuộc với Java, thì bạn có thể biết khối Try-Catch, nơi chúng ta thường phát hiện ra một lỗi và bắt giống nhau trong khối catch . Trong Haskell, chúng ta cũng có chức năng tương tự để bắt lỗi thời gian chạy.

Định nghĩa hàm của try trông giống như “try :: Exception e => IO a -> IO (Either ea)”. Hãy xem đoạn mã ví dụ sau. Nó chỉ ra cách bạn có thể bắt được ngoại lệ “Chia cho 0”.

Ở đây, chúng tôi đã tạo một tệp văn bản có tên "abc.txt". Tiếp theo, chúng tôi đã chèn một câu lệnh trong tệp bằng lệnh writeFile . Cuối cùng, chúng ta đã sử dụng lệnh readFile để in nội dung của tệp trên bảng điều khiển. Mã của chúng tôi sẽ tạo ra kết quả sau:
I am just experimenting here.
Ngoại lệ
Một ngoại lệ có thể được coi là một lỗi trong mã. Đó là một tình huống mà trình biên dịch không nhận được đầu ra mong đợi trong thời gian chạy. Giống như bất kỳ ngôn ngữ lập trình tốt nào khác, Haskell cung cấp một cách để thực hiện xử lý ngoại lệ.
Nếu bạn đã quen thuộc với Java, thì bạn có thể biết khối Try-Catch, nơi chúng ta thường phát hiện ra một lỗi và bắt giống nhau trong khối catch . Trong Haskell, chúng ta cũng có chức năng tương tự để bắt lỗi thời gian chạy.
Định nghĩa hàm của try trông giống như "try :: Exception e => IO a -> IO (Either ea)". Hãy xem đoạn mã ví dụ sau. Nó chỉ ra cách bạn có thể bắt được ngoại lệ "Chia cho 0".
import Control.Exception 

main = do 
   result <- try (evaluate (5 `div` 0)) :: IO (Either SomeException Int) 
   case result of 
      Left ex   -> putStrLn $ "Caught exception: " ++ show ex 
      Right val -> putStrLn $ "The answer was: " ++ show val 

Trong ví dụ trên, chúng tôi đã sử dụng hàm try có sẵn của mô-đun Control.Exception , do đó chúng tôi đang bắt trước ngoại lệ. Đoạn mã phía trên sẽ mang lại kết quả bên dưới trong màn hình.

Caught exception: divide by zero

Haskell – Functor (xem thêm)

The post Haskell – Thành phần chức năng appeared first on Dongthoigian.

]]>
https://dongthoigian.net/haskell-thanh-phan-chuc-nang/feed/ 0
Haskell – Thêm về các chức năng https://dongthoigian.net/haskell-them-ve-cac-chuc-nang/ https://dongthoigian.net/haskell-them-ve-cac-chuc-nang/#respond Fri, 27 May 2022 04:41:45 +0000 https://dongthoigian.net/?p=13863 Nhiều loại hàm Haskell và sử dụng các cách khác nhau để gọi các hàm đó.

The post Haskell – Thêm về các chức năng appeared first on Dongthoigian.

]]>
Cho đến bây giờ, chúng ta đã thảo luận về nhiều loại hàm Haskell và sử dụng các cách khác nhau để gọi các hàm đó. Trong chương này, chúng ta sẽ tìm hiểu về một số hàm cơ bản có thể dễ dàng sử dụng trong Haskell mà không cần nhập bất kỳ lớp Type đặc biệt nào. Hầu hết các chức năng này là một phần của các chức năng bậc cao khác.

Chức năng đầu (Head Function)

Chức năng Head hoạt động trên một Danh sách. Nó trả về đối số đầu tiên về cơ bản là một danh sách. Trong ví dụ sau, chúng tôi đang chuyển một danh sách có 10 giá trị và chúng tôi đang tạo phần tử đầu tiên của danh sách đó bằng cách sử dụng hàm head

main = do 
   let x = [1..10]   
   putStrLn "Our list is:"  
   print (x) 
   putStrLn "The first element of the list is:" 
   print (head x)

Nó sẽ tạo ra kết quả sau:

Our list is: 
[1,2,3,4,5,6,7,8,9,10]
The first element of the list is:
1

Tail Function

Đuôi là chức năng bổ sung cho chức năng của đầu . Nó lấy một danh sách làm đầu vào và tạo ra toàn bộ danh sách mà không có phần đầu. Điều đó có nghĩa là, hàm tail trả về toàn bộ danh sách mà không có phần tử đầu tiên. Hãy xem ví dụ sau:

main = do 
   let x = [1..10]   
   putStrLn "Our list is:"  
   print (x) 
   putStrLn "The tail of our list is:" 
   print (tail x)

Nó sẽ tạo ra kết quả sau: Danh sách của chúng tôi là:

[1,2,3,4,5,6,7,8,9,10]
Phần cuối của danh sách của chúng tôi là:
[2,3,4,5,6,7,8,9,10]

Chức năng cuối cùng Last Function

Như tên cho thấy, nó mang lại phần tử cuối cùng của danh sách được cung cấp làm đầu vào. Kiểm tra ví dụ sau.

main = do 
   let x = [1..10]   
   putStrLn "Our list is:"  
   print (x) 
   putStrLn "The last element of our list is:" 
   print (last x)

Nó sẽ tạo ra kết quả sau:

Our list is:
[1,2,3,4,5,6,7,8,9,10]
The last element of our list is:
10

Chức năng Init Init Function

Init hoạt động hoàn toàn ngược lại với hàm tail . Nó lấy một danh sách làm đối số và trả về toàn bộ danh sách mà không có mục nhập cuối cùng

main = do 
   let x = [1..10]   
   putStrLn "Our list is:"  
   print (x) 
   putStrLn "Our list without the last entry:"  
   print (init x) 

Bây giờ, hãy quan sát đầu ra của nó –

Our list is:
[1,2,3,4,5,6,7,8,9,10]
Our list without the last entry:
[1,2,3,4,5,6,7,8,9]

Hàm Null Null Function

Null là một hàm kiểm tra Boolean hoạt động trên một Chuỗi và chỉ trả về True khi danh sách đã cho trống, nếu không, nó trả về False . Đoạn mã sau kiểm tra xem danh sách được cung cấp có trống hay không.

main = do 
   let x = [1..10]   
   putStrLn "Our list is:"  
   print (x) 
   putStrLn "Is our list empty?"  
   print (null x)
Nó sẽ tạo ra kết quả sau:
Our list is:
[1,2,3,4,5,6,7,8,9,10]
Is our list empty?
False

Chức năng Đảo ngược Reverse Function

Nó hoạt động trên đầu vào Chuỗi và chuyển toàn bộ đầu vào thành thứ tự ngược lại và kết quả là một đầu ra. Dưới đây là cơ sở mã cho chức năng này.

main = do 
   let x = [1..10]  
   putStrLn "Our list is:" 
   print (x) 
   putStrLn "The list in Reverse Order is:" 
   print (reverse x)

Nó sẽ tạo ra kết quả sau: Danh sách của chúng tôi là:

Our list is:
[1,2,3,4,5,6,7,8,9,10]
The list in Reverse Order is:
[10,9,8,7,6,5,4,3,2,1]

Hàm chiều dài Length Function

Hàm này được sử dụng để tính toán độ dài của danh sách được đưa ra dưới dạng một đối số. Hãy xem ví dụ sau:

main = do 
   let x = [1..10]   
   putStrLn "Our list is:" 
   print (x) 
   putStrLn "The length of this list is:" 
   print (length x)

Chúng tôi có 10 phần tử trong danh sách của mình, do đó mã của chúng tôi sẽ mang lại 10 phần tử như đầu ra.

Our list is:
[1,2,3,4,5,6,7,8,9,10]
The length of this list is:
10

Thực hiện chức năng Take Function

Hàm Take được sử dụng để tạo một chuỗi con từ một Chuỗi khác. Đoạn mã sau đây cho thấy cách bạn có thể sử dụng hàm take trong Haskell:

main = print(take 5 ([1 .. 10])) 

Mã tạo một chuỗi con chứa 5 phần tử từ danh sách được cung cấp –

[1,2,3,4,5]

Chức năng Drop Function

Hàm này cũng được sử dụng để tạo một chuỗi con. Nó hoạt động như ngược lại với hàm lấy . Hãy xem đoạn mã sau:

main = print(drop 5 ([1 .. 10])) 

Mã loại bỏ 5 phần tử đầu tiên khỏi danh sách được cung cấp và in 5 phần tử còn lại. Nó sẽ tạo ra kết quả sau:

[6,7,8,9,10]

Chức năng tối đa Maximum Function 

Hàm này được sử dụng để tìm phần tử có giá trị lớn nhất từ ​​danh sách được cung cấp. Hãy để chúng tôi xem cách sử dụng nó trong thực tế –

main = do 
   let x = [1,45,565,1245,02,2]   
   putStrLn "The maximum value element of the list is:"  
   print (maximum x)

Đoạn mã trên sẽ tạo ra kết quả sau:

The maximum value element of the list is:

1245

Chức năng tối thiểu Minimum Function

Hàm này được sử dụng để tìm phần tử có giá trị nhỏ nhất từ ​​danh sách được cung cấp. Nó chỉ đối lập với chức năng tối đa

main = do 
   let x = [1,45,565,1245,02,2]   
   putStrLn "The minimum value element of the list is:"  
   print (minimum x)
    

Đầu ra của đoạn mã trên là –

The minimum value element of the list is:

1

Hàm tính tổng Sum Function

Như tên cho thấy, hàm này trả về tổng của tất cả các phần tử có trong danh sách được cung cấp. Đoạn mã sau lấy danh sách 5 phần tử và trả về tổng kết của chúng dưới dạng đầu ra.

main = do 
   let x = [1..5] 
   putStrLn "Our list is:" 
   print (x) 
   putStrLn "The summation of the list elements is:" 
   print (sum x)

Nó sẽ tạo ra kết quả sau:

Danh sách của chúng tôi là:
[1,2,3,4,5]
Tổng của các phần tử danh sách là:
15

Chức năng sản phẩm Product Function

Bạn có thể sử dụng hàm này để nhân tất cả các phần tử trong danh sách và in giá trị của nó.

Nó sẽ tạo ra kết quả sau:
Danh sách của chúng tôi là:
[1,2,3,4,5]
Tổng của các phần tử danh sách là:
15
Chức năng sản phẩm Product Function

Bạn có thể sử dụng hàm này để nhân tất cả các phần tử trong danh sách và in giá trị của nó.
main = do 
   let x = [1..5] 
   putStrLn "Our list is:" 
   print (x) 
   putStrLn "The multiplication of the list elements is:" 
   print (product x)
     

Mã của chúng tôi sẽ tạo ra kết quả sau:

Our list is:

[1,2,3,4,5]

The multiplication of the list elements is:

120

Chức năng Elem Elem Function

Chức năng này được sử dụng để kiểm tra xem danh sách được cung cấp có chứa một phần tử cụ thể hay không. Theo đó, nó trả về true hoặc false .

Đoạn mã sau kiểm tra xem danh sách các phần tử được cung cấp có chứa giá trị 786 hay không.

main = do 
   let x = [1,45,155,1785] 
   putStrLn "Our list is:" 
   print (x) 
   putStrLn "Does it contain 786?" 
   print (elem 786 (x))

Nó sẽ tạo ra kết quả sau:

Our list is:

[1,45,155,1785]

Does it contain 786?

False Sử dụng mã tương tự để kiểm tra xem danh sách được cung cấp có chứa giá trị 1785 hay không.

Haskell – Thành phần chức năng (xem thêm)

The post Haskell – Thêm về các chức năng appeared first on Dongthoigian.

]]>
https://dongthoigian.net/haskell-them-ve-cac-chuc-nang/feed/ 0
Haskell – Chức năng https://dongthoigian.net/haskell-chuc-nang/ https://dongthoigian.net/haskell-chuc-nang/#respond Fri, 27 May 2022 04:09:31 +0000 https://dongthoigian.net/?p=13860 Các hàm đóng một vai trò quan trọng trong Haskell, vì nó là một ngôn ngữ lập trình hàm. Giống như các ngôn ngữ khác, Haskell có định nghĩa và khai báo chức năng của riêng nó. Khai báo hàm bao gồm tên hàm và danh sách đối số của nó

The post Haskell – Chức năng appeared first on Dongthoigian.

]]>
Các hàm đóng một vai trò quan trọng trong Haskell, vì nó là một ngôn ngữ lập trình hàm. Giống như các ngôn ngữ khác, Haskell có định nghĩa và khai báo chức năng của riêng nó.

  • Khai báo hàm bao gồm tên hàm và danh sách đối số của nó cùng với đầu ra của nó.
  • Định nghĩa hàm là nơi bạn thực sự xác định một hàm.

Chúng ta hãy lấy một ví dụ nhỏ về hàm add để hiểu chi tiết khái niệm này.

add :: Integer -> Integer -> Integer   --function declaration 
add x y =  x + y                       --function definition 

main = do 
   putStrLn "The addition of the two numbers is:"  
   print(add 2 5)    --calling a function 

Ở đây, chúng ta đã khai báo hàm của mình ở dòng đầu tiên và ở dòng thứ hai, chúng ta đã viết hàm thực của mình sẽ nhận hai đối số và tạo ra một đầu ra kiểu số nguyên.

Giống như hầu hết các ngôn ngữ khác, Haskell bắt đầu biên dịch mã từ phương thức chính . Mã của chúng tôi sẽ tạo ra kết quả sau:

The addition of the two numbers is:
7

Khớp mẫu

Khớp mẫu là quá trình đối sánh loại biểu thức cụ thể. Nó không là gì ngoài một kỹ thuật để đơn giản hóa mã của bạn. Kỹ thuật này có thể được triển khai vào bất kỳ loại lớp Type nào. If-Else có thể được sử dụng như một tùy chọn thay thế của đối sánh mẫu.

Đối sánh mẫu có thể được coi là một biến thể của đa hình động, trong đó tại thời gian chạy, các phương thức khác nhau có thể được thực thi tùy thuộc vào danh sách đối số của chúng. Hãy xem khối mã sau. Ở đây chúng tôi đã sử dụng kỹ thuật So khớp mẫu để tính giai thừa của một số.

fact :: Int -> Int 
fact 0 = 1 
fact n = n * fact ( n - 1 ) 

main = do 
   putStrLn "The factorial of 5 is:" 
   print (fact 5)

Tất cả chúng ta đều biết cách tính giai thừa của một số. Trình biên dịch sẽ bắt đầu tìm kiếm một hàm được gọi là “fact” với một đối số. Nếu đối số không bằng 0, thì số sẽ tiếp tục gọi cùng một hàm với số ít hơn 1 so với đối số thực. Khi mẫu của đối số khớp chính xác với 0, nó sẽ gọi mẫu của chúng ta là “fact 0 = 1”. Mã của chúng tôi sẽ tạo ra kết quả sau:

The factorial of 5 is:
120

Lính canh

Bảo vệ là một khái niệm rất giống với đối sánh mẫu. Trong đối sánh mẫu, chúng tôi thường so khớp một hoặc nhiều biểu thức, nhưng chúng tôi sử dụng bảo vệ để kiểm tra một số thuộc tính của một biểu thức.

Mặc dù nên sử dụng đối sánh mẫu thay vì bảo vệ , nhưng từ quan điểm của nhà phát triển, bảo vệ dễ đọc và đơn giản hơn. Đối với những người sử dụng lần đầu, bảo vệ có thể trông rất giống với câu lệnh If-Else, nhưng chúng khác nhau về chức năng. Trong đoạn mã sau, chúng tôi đã sửa đổi chương trình giai thừa của mình bằng cách sử dụng khái niệm lính canh .

Lính canh
Bảo vệ là một khái niệm rất giống với đối sánh mẫu. Trong đối sánh mẫu, chúng tôi thường so khớp một hoặc nhiều biểu thức, nhưng chúng tôi sử dụng bảo vệ để kiểm tra một số thuộc tính của một biểu thức.
Mặc dù nên sử dụng đối sánh mẫu thay vì bảo vệ , nhưng từ quan điểm của nhà phát triển, bảo vệ dễ đọc và đơn giản hơn. Đối với những người sử dụng lần đầu, bảo vệ có thể trông rất giống với câu lệnh If-Else, nhưng chúng khác nhau về chức năng.
Trong đoạn mã sau, chúng tôi đã sửa đổi chương trình giai thừa của mình bằng cách sử dụng khái niệm lính canh .
fact :: Integer -> Integer 
fact n | n == 0 = 1 
       | n /= 0 = n * fact (n-1) 
main = do 
   putStrLn "The factorial of 5 is:"  
   print (fact 5) 

Ở đây, chúng tôi đã khai báo hai lính canh , cách nhau bởi “|” và gọi hàm fact từ main . Bên trong, trình biên dịch sẽ hoạt động theo cách tương tự như trong trường hợp khớp mẫu để mang lại kết quả sau:

The factorial of 5 is:
120

Mệnh đề Where

Đâu là một từ khóa hoặc hàm có sẵn có thể được sử dụng trong thời gian chạy để tạo ra kết quả mong muốn. Nó có thể rất hữu ích khi việc tính toán hàm trở nên phức tạp.

Hãy xem xét một tình huống trong đó đầu vào của bạn là một biểu thức phức tạp với nhiều tham số. Trong những trường hợp như vậy, bạn có thể chia toàn bộ biểu thức thành các phần nhỏ bằng cách sử dụng mệnh đề “where”.

Trong ví dụ sau, chúng ta đang sử dụng một biểu thức toán học phức tạp. Chúng tôi sẽ chỉ cho bạn cách bạn có thể tìm nghiệm nguyên của phương trình đa thức [x ^ 2 – 8x + 6] bằng cách sử dụng Haskell.

roots :: (Float, Float, Float) -> (Float, Float)  
roots (a,b,c) = (x1, x2) where 
   x1 = e + sqrt d / (2 * a) 
   x2 = e - sqrt d / (2 * a) 
   d = b * b - 4 * a * c  
   e = - b / (2 * a)  
main = do 
   putStrLn "The roots of our Polynomial equation are:" 
   print (roots(1,-8,6))

Lưu ý mức độ phức tạp của biểu thức của chúng ta để tính các nghiệm nguyên của hàm đa thức đã cho. Nó khá phức tạp. Do đó, chúng tôi đang phá vỡ biểu thức bằng cách sử dụng mệnh đề where . Đoạn mã trên sẽ tạo ra kết quả sau:

The roots of our Polynomial equation are:
(7.1622777,0.8377223)

Hàm đệ quy

Đệ quy là một tình huống mà một hàm gọi chính nó lặp đi lặp lại. Haskell không cung cấp bất kỳ cơ sở lặp lại bất kỳ biểu thức nào nhiều hơn một lần. Thay vào đó, Haskell muốn bạn chia toàn bộ chức năng của mình thành một tập hợp các chức năng khác nhau và sử dụng kỹ thuật đệ quy để triển khai chức năng của bạn.

Chúng ta hãy xem xét lại ví dụ về đối sánh mẫu của chúng ta, nơi chúng ta đã tính giai thừa của một số. Tìm giai thừa của một số là một trường hợp cổ điển của việc sử dụng Đệ quy. Ở đây, bạn có thể, “So khớp mẫu khác với đệ quy như thế nào?” Sự khác biệt giữa hai điều này nằm ở cách chúng được sử dụng. So khớp mẫu hoạt động khi thiết lập ràng buộc đầu cuối, trong khi đệ quy là một lời gọi hàm.

Trong ví dụ sau, chúng tôi đã sử dụng cả đối sánh mẫu và đệ quy để tính giai thừa của 5.

fact :: Int -> Int 
fact 0 = 1 
fact n = n * fact ( n - 1 ) 

main = do 
   putStrLn "The factorial of 5 is:" 
   print (fact 5) 

Nó sẽ tạo ra kết quả sau:

The factorial of 5 is:
120

Chức năng đặt hàng cao hơn

Cho đến bây giờ, những gì chúng ta đã thấy là các hàm Haskell nhận một kiểu làm đầu vào và tạo ra một kiểu khác làm đầu ra, điều này khá giống với các ngôn ngữ mệnh lệnh khác. Các hàm thứ tự cao hơn là một tính năng độc đáo của Haskell nơi bạn có thể sử dụng một hàm làm đối số đầu vào hoặc đầu ra.

Mặc dù nó là một khái niệm ảo, nhưng trong các chương trình thế giới thực, mọi chức năng mà chúng ta xác định trong Haskell đều sử dụng cơ chế bậc cao hơn để cung cấp đầu ra. Nếu bạn có cơ hội xem xét hàm thư viện của Haskell, thì bạn sẽ thấy rằng hầu hết các hàm thư viện đã được viết theo cách thức cao hơn. Hãy để chúng tôi lấy một ví dụ trong đó chúng tôi sẽ nhập một bản đồ hàm bậc cao có sẵn và sử dụng bản đồ đó để triển khai một hàm bậc cao khác theo sự lựa chọn của chúng ta.

import Data.Char  
import Prelude hiding (map) 

map :: (a -> b) -> [a] -> [b] 
map _ [] = [] 
map func (x : abc) = func x : map func abc  
main = print $ map toUpper "dongthoigian.net" 

Trong ví dụ trên, chúng ta đã sử dụng hàm toUpper của Type Class Char để chuyển đầu vào của chúng ta thành chữ hoa. Ở đây, phương thức “map” đang nhận một hàm làm đối số và trả về kết quả đầu ra được yêu cầu. Đây là đầu ra của nó

sh-4.3$ ghc -O2 --make *.hs -o main -threaded -rtsopts
sh-4.3$ main
"dongthoigian.net" 

Lambda Expression

Đôi khi chúng ta phải viết một hàm chỉ được sử dụng một lần, trong toàn bộ vòng đời của một ứng dụng. Để đối phó với loại tình huống này, các nhà phát triển Haskell sử dụng một khối ẩn danh khác được gọi là biểu thức lambda hoặc hàm lambda .

Một hàm không có định nghĩa được gọi là hàm lambda. Một hàm lambda được biểu thị bằng ký tự “\”. Chúng ta hãy lấy ví dụ sau, nơi chúng ta sẽ tăng giá trị đầu vào lên 1 mà không cần tạo bất kỳ hàm nào.

main = do 
   putStrLn "The successor of 4 is:"  
   print ((\x -> x + 1) 4)

Ở đây, chúng tôi đã tạo một hàm ẩn danh không có tên. Nó lấy số nguyên 4 làm đối số và in ra giá trị đầu ra. Về cơ bản chúng ta đang vận hành một hàm mà không cần khai báo nó đúng cách. Đó là vẻ đẹp của biểu thức lambda. Biểu thức lambda của chúng tôi sẽ tạo ra kết quả sau:

sh-4.3$ main
The successor of 4 is:
5

Haskell – Thêm về các chức năng (xem thêm)

The post Haskell – Chức năng appeared first on Dongthoigian.

]]>
https://dongthoigian.net/haskell-chuc-nang/feed/ 0
Haskell – Types and Type Class https://dongthoigian.net/haskell-types-and-type-class/ https://dongthoigian.net/haskell-types-and-type-class/#respond Fri, 27 May 2022 03:41:42 +0000 https://dongthoigian.net/?p=13857 Trong Haskell, mọi câu lệnh được coi là một biểu thức toán học và phạm trù của biểu thức này được gọi là Kiểu 

The post Haskell – Types and Type Class appeared first on Dongthoigian.

]]>
Haskell là một ngôn ngữ chức năng và nó được nhập đúng cách, có nghĩa là kiểu dữ liệu được sử dụng trong toàn bộ ứng dụng sẽ được trình biên dịch biết tại thời điểm biên dịch.

Loại kiểu sẵn có

Trong Haskell, mọi câu lệnh được coi là một biểu thức toán học và phạm trù của biểu thức này được gọi là Kiểu . Bạn có thể nói rằng “Kiểu” là kiểu dữ liệu của biểu thức được sử dụng tại thời điểm biên dịch.

Để tìm hiểu thêm về Type , chúng ta sẽ sử dụng lệnh “: t”. Nói một cách chung chung, Type có thể được coi là một giá trị, trong khi Type Class có thể được coi là một tập hợp các loại Type tương tự nhau. Trong chương này, chúng ta sẽ tìm hiểu về các loại Inbuilt khác nhau.

Int

Int là một lớp kiểu đại diện cho dữ liệu kiểu Số nguyên. Mọi số nguyên trong phạm vi từ 2147483647 đến -2147483647 đều thuộc loại Int . Trong ví dụ sau, hàm fType () sẽ hoạt động theo kiểu của nó được xác định.

fType :: Int -> Int -> Int 
fType x y = x*x + y*y
main = print (fType 2 4) 

Ở đây, chúng ta đã đặt kiểu của hàm fType () là int . Hàm nhận hai giá trị int và trả về một giá trị int . Nếu bạn biên dịch và thực thi đoạn mã này, thì nó sẽ tạo ra kết quả sau:

sh-4.3$ ghc -O2 --make *.hs -o main -threaded -rtsopts 
sh-4.3$ main
20

Integer

Số nguyên có thể được coi là một tập siêu của Int . Giá trị này không bị giới hạn bởi bất kỳ số nào, do đó một Số nguyên có thể có độ dài bất kỳ mà không có bất kỳ giới hạn nào. Để thấy sự khác biệt cơ bản giữa kiểu Int và Integer , chúng ta hãy sửa đổi đoạn mã trên như sau:

fType :: Int -> Int -> Int 
fType x y = x*x + y*y 
main = print (fType 212124454 44545454454554545445454544545)

Nếu bạn biên dịch đoạn mã trên, thông báo lỗi sau sẽ được đưa ra:

main.hs:3:31: Warning:            
   Literal 44545454454554545445454544545 is out of the Int range -
   9223372036854775808..9223372036854775807 
Linking main ...

Lỗi này xảy ra do hàm fType () của chúng tôi mong đợi một giá trị kiểu Int và chúng tôi đang chuyển một số giá trị kiểu Int lớn thực sự. Để tránh lỗi này, Chúng ta hãy sửa đổi kiểu “Int” bằng “Số nguyên” và quan sát sự khác biệt.

fType :: Integer -> Integer -> Integer 
fType x y = x*x + y*y 
main = print (fType 212124454 4454545445455454545445445454544545)

Bây giờ, nó sẽ tạo ra kết quả sau:

sh-4.3$ main
1984297512562793395882644631364297686099210302577374055141

Float

Hãy xem đoạn mã sau. Nó cho thấy cách hoạt động của kiểu Float trong Haskell

fType :: Float -> Float -> Float 
fType x y = x*x + y*y 
main = print (fType 2.5 3.8)

Hàm nhận hai giá trị float làm đầu vào và mang lại một giá trị float khác làm đầu ra. Khi bạn biên dịch và thực thi mã này, nó sẽ tạo ra kết quả sau:

sh-4.3$ main
20.689999 
Double
Double là một số dấu phẩy động với độ chính xác gấp đôi ở cuối. Hãy xem ví dụ sau:
Double
Double là một số dấu phẩy động với độ chính xác gấp đôi ở cuối. Hãy xem ví dụ sau:
fType :: Double -> Double -> Double 
fType x y = x*x + y*y 
main = print (fType 2.56 3.81)

Khi bạn thực thi đoạn mã trên, nó sẽ tạo ra kết quả sau:

sh-4.3$ main 
21.0697

Bool

Bool là một kiểu Boolean. Nó có thể là Đúng hoặc Sai. Thực thi đoạn mã sau để hiểu cách hoạt động của kiểu Bool trong Haskell:

main = do  
   let x = True 
   
   if x == False 
      then putStrLn "X matches with Bool Type" 
   else putStrLn "X is not a Bool Type" 

Ở đây, chúng tôi đang xác định một biến “x” là Bool và so sánh nó với một giá trị Boolean khác để kiểm tra tính nguyên bản của nó. Nó sẽ tạo ra kết quả sau:

sh-4.3$ main
X is not a Bool Type 

Char

Char đại diện cho các ký tự. Bất cứ thứ gì trong một trích dẫn duy nhất đều được coi là một Nhân vật. Trong đoạn mã sau, chúng tôi đã sửa đổi hàm fType () trước đó của mình để chấp nhận giá trị Char và trả về giá trị Char dưới dạng đầu ra.

fType :: Char-> Char 
fType x = 'K' 
main = do  
   let x = 'v' 
   print (fType x) 

Đoạn mã trên sẽ gọi hàm fType () với giá trị char là ‘v’ nhưng nó trả về một giá trị char khác, đó là ‘K’. Đây là đầu ra của nó

sh-4.3$ main 
'K'

Lưu ý rằng chúng ta sẽ không sử dụng các kiểu này một cách rõ ràng vì Haskell đủ thông minh để bắt kiểu trước khi nó được khai báo. Trong các chương tiếp theo của hướng dẫn này, chúng ta sẽ thấy các kiểu và lớp Kiểu khác nhau làm cho Haskell trở thành một ngôn ngữ được đánh máy mạnh mẽ như thế nào.

EQ Type Class

Lớp kiểu EQ là một giao diện cung cấp chức năng kiểm tra tính bình đẳng của một biểu thức. Bất kỳ lớp Kiểu nào muốn kiểm tra tính bình đẳng của một biểu thức phải là một phần của Lớp Kiểu EQ này.

Tất cả các lớp Loại tiêu chuẩn được đề cập ở trên là một phần của lớp EQ này . Bất cứ khi nào chúng tôi kiểm tra bất kỳ sự bình đẳng nào bằng cách sử dụng bất kỳ kiểu nào được đề cập ở trên, chúng tôi thực sự đang thực hiện một cuộc gọi đến lớp kiểu EQ . Trong ví dụ sau, chúng tôi đang sử dụng Loại EQ nội bộ bằng thao tác “==” hoặc “/ =”

main = do 
   if 8 /= 8 
      then putStrLn "The values are Equal" 
   else putStrLn "The values are not Equal"

Nó sẽ mang lại kết quả sau:

sh-4.3$ main 
The values are not Equal 

Ord Type Class

Ord là một lớp giao diện khác cung cấp cho chúng ta chức năng đặt hàng. Tất cả các loại mà chúng tôi đã sử dụng cho đến nay là một phần của giao diện Ord này . Giống như giao diện EQ, giao diện Ord có thể được gọi bằng cách sử dụng “>”, “<“, “<=”, “> =”, “so sánh”.

ví dụ dưới đây, nơi chúng tôi đã sử dụng chức năng “so sánh”

main = print (4 <= 2) 

Tại đây, trình biên dịch Haskell sẽ kiểm tra xem 4 có nhỏ hơn hoặc bằng 2. Vì không, mã sẽ tạo ra kết quả sau:

sh-4.3$ main 
False

Show

Show có chức năng in đối số của nó dưới dạng Chuỗi. Dù có thể là đối số của nó, nó luôn in ra kết quả dưới dạng một Chuỗi. Trong ví dụ sau, chúng tôi sẽ in toàn bộ danh sách bằng giao diện này. “show” có thể được sử dụng để gọi giao diện này.

main = print (show [1..10]) 

Nó sẽ tạo ra kết quả sau trên bảng điều khiển. Ở đây, dấu ngoặc kép chỉ ra rằng đó là một giá trị kiểu Chuỗi.

sh-4.3$ main 
"[1,2,3,4,5,6,7,8,9,10]" 

Read

Giao diện Đọc thực hiện tương tự như Hiển thị, nhưng nó sẽ không in kết quả ở định dạng Chuỗi. Trong đoạn mã sau, chúng tôi đã sử dụng đọc giao diện để đọc một chuỗi giá trị và chuyển đổi tương tự thành một giá trị Int.

main = print (readInt "12") 
readInt :: String -> Int 
readInt = read 

Ở đây, chúng ta đang chuyển một biến Chuỗi (“12”) đến phương thức readInt , lần lượt nó sẽ trả về 12 (một giá trị Int) sau khi chuyển đổi. Đây là đầu ra của nó –

sh-4.3$ main 
12

Enum

Enum là một loại lớp Type khác cho phép thực hiện chức năng tuần tự hoặc có thứ tự trong Haskell. Lớp Type này có thể được truy cập bằng các lệnh như Succ, Pred, Bool, Char , v.v. Đoạn mã sau đây cho biết cách tìm giá trị kế tiếp của 12.

Enum
Enum là một loại lớp Type khác cho phép thực hiện chức năng tuần tự hoặc có thứ tự trong Haskell. Lớp Type này có thể được truy cập bằng các lệnh như Succ, Pred, Bool, Char , v.v.
Đoạn mã sau đây cho biết cách tìm giá trị kế tiếp của 12.
main = print (succ 12)

main = print (succ 12) 

Nó sẽ tạo ra kết quả sau:

sh-4.3$ main
13

Bounded

Tất cả các loại có giới hạn trên và dưới đều thuộc Loại Loại này. Ví dụ: dữ liệu kiểu Int có giới hạn tối đa là “9223372036854775807” và giới hạn tối thiểu là “-9223372036854775808”. Đoạn mã sau đây cho thấy cách Haskell xác định giới hạn tối đa và tối thiểu của loại Int.

main = do 
   print (maxBound :: Int) 
   print (minBound :: Int) 

Nó sẽ tạo ra kết quả sau:

sh-4.3$ main
9223372036854775807
-9223372036854775808

Bây giờ, hãy cố gắng tìm giới hạn tối đa và tối thiểu của các loại Char, Float và Bool.

Num

Lớp kiểu này được sử dụng cho các phép toán số. Các kiểu như Int, Integer, Float và Double thuộc lớp Type này. Hãy xem đoạn mã sau:

main = do 
   print(2 :: Int)  
   print(2 :: Float) 

Nó sẽ tạo ra kết quả sau:

sh-4.3$ main
2
2.0

Integral

Tích phân có thể được coi là một lớp con của Lớp Loại Num. Lớp Num Type chứa tất cả các loại số, trong khi lớp Integral type chỉ được sử dụng cho các số tích phân. Int và Integer là các kiểu thuộc lớp Kiểu này.

Floating

Giống như Integral, Floating cũng là một phần của lớp Num Type, nhưng nó chỉ chứa các số dấu phẩy động. Do đó, Float và Double thuộc loại này.

Custom Type Class

Giống như bất kỳ ngôn ngữ lập trình nào khác, Haskell cho phép các nhà phát triển xác định các kiểu do người dùng xác định. Trong ví dụ sau, chúng tôi sẽ tạo một kiểu do người dùng xác định và sử dụng nó.

data Area = Circle Float Float Float  
surface :: Area -> Float   
surface (Circle _ _ r) = pi * r ^ 2   
main = print (surface $ Circle 10 20 10 ) 

Ở đây, chúng tôi đã tạo một loại mới có tên là Khu vực . Tiếp theo, chúng ta đang sử dụng kiểu này để tính diện tích của một hình tròn. Trong ví dụ trên, “surface” là một hàm lấy Area làm đầu vào và tạo Float làm đầu ra.

Hãy nhớ rằng “dữ liệu” là một từ khóa ở đây và tất cả các loại do người dùng xác định trong Haskell luôn bắt đầu bằng một chữ cái viết hoa. Nó sẽ tạo ra kết quả sau:

sh-4.3$ main
314.15927

Haskell – Chức năng (xem thêm)

The post Haskell – Types and Type Class appeared first on Dongthoigian.

]]>
https://dongthoigian.net/haskell-types-and-type-class/feed/ 0
Haskell – Các toán tử cơ bản https://dongthoigian.net/haskell-cac-toan-tu-co-ban/ https://dongthoigian.net/haskell-cac-toan-tu-co-ban/#respond Thu, 26 May 2022 08:15:52 +0000 https://dongthoigian.net/?p=13848 Haskell xử lý thông minh một số phép toán cơ bản như cộng, trừ, nhân,

The post Haskell – Các toán tử cơ bản appeared first on Dongthoigian.

]]>
Trong chương này, chúng ta sẽ tìm hiểu về các toán tử khác nhau được sử dụng trong Haskell. Giống như các ngôn ngữ lập trình khác, Haskell xử lý thông minh một số phép toán cơ bản như cộng, trừ, nhân, … Trong các chương sắp tới, chúng ta sẽ tìm hiểu thêm về các toán tử khác nhau và cách sử dụng chúng.

Trong chương này, sẽ sử dụng các toán tử khác nhau trong Haskell bằng nền tảng trực tuyến Hãy nhớ rằng chúng ta chỉ sử dụng các số kiểu số nguyên vì chúng ta sẽ tìm hiểu thêm về các số kiểu thập phân trong các chương tiếp theo.

Toán tử bổ sung

Như tên cho thấy, toán tử cộng (+) được sử dụng cho chức năng cộng. Mã mẫu sau đây cho thấy cách bạn có thể thêm hai số nguyên trong Haskell:

main = do 
   let var1 = 2 
   let var2 = 3 
   putStrLn "The addition of the two numbers is:" 
   print(var1 + var2) 

Trong tệp trên, chúng tôi đã tạo hai biến riêng biệt var1 và var2 . Cuối cùng, chúng tôi đang in kết quả bằng cách sử dụng Ngoài nhà điều hành. Sử dụng nút biên dịch và thực thi để chạy mã của bạn.

Mã này sẽ tạo ra kết quả sau trên màn hình:

The addition of the two numbers is: 5

Toán tử phép trừ

Như tên cho thấy, toán tử này được sử dụng cho hoạt động trừ. Mã mẫu sau đây cho thấy cách bạn có thể trừ hai số nguyên trong Haskell:

main = do 
   let var1 = 10 
   let var2 = 6 
   putStrLn "The Subtraction of the two numbers is:" 
   print(var1 - var2)

Trong ví dụ này, chúng tôi đã tạo hai biến var1 và var2 . Sau đó, chúng ta sử dụng toán tử trừ (-) để trừ hai giá trị.

Mã này sẽ tạo ra kết quả sau trên màn hình:

The Subtraction of the two numbers is: 4

Toán tử nhân

Toán tử này được sử dụng cho các phép toán nhân. Đoạn mã sau đây cho thấy cách nhân hai số trong Haskell bằng Toán tử nhân

main = do 
   let var1 = 2 
   let var2 = 3 
   putStrLn "The Multiplication of the Two Numbers is:" 
   print(var1 * var2)

Mã này sẽ tạo ra kết quả sau, khi bạn chạy nó trong nền tảng trực tuyến của chúng tôi –

The Multiplication of the Two Numbers is: 6 

Người điều hành bộ phận

Hãy xem đoạn mã sau. Nó chỉ ra cách bạn có thể chia hai số trong Haskell

main = do 
   let var1 = 12 
   let var2 = 3 
   putStrLn "The Division of the Two Numbers is:" 
   print(var1/var2)

Nó sẽ tạo ra kết quả sau:

The Division of the Two Numbers is: 4.0 

Toán tử dãy / dãy

Sequence hoặc Range là một toán tử đặc biệt trong Haskell. Nó được ký hiệu là “(..)”. Bạn có thể sử dụng toán tử này trong khi khai báo danh sách với một chuỗi giá trị.

Nếu bạn muốn in tất cả các giá trị từ 1 đến 10, thì bạn có thể sử dụng một cái gì đó như “[1..10]”. Tương tự, nếu bạn muốn tạo tất cả các bảng chữ cái từ “a” đến “z”, thì bạn chỉ cần nhập “[a..z]” . Đoạn mã sau đây cho thấy cách bạn có thể sử dụng toán tử Trình tự để in tất cả các giá trị từ 1 đến 10

main :: IO() 
main = do 
   print [1..10]

Nó sẽ tạo ra kết quả sau: [1,2,3,4,5,6,7,8,9,10]

Haskell – Ra quyết định

Ra quyết định là một tính năng cho phép lập trình viên áp dụng một điều kiện trong dòng mã. Người lập trình có thể thực hiện một tập hợp các lệnh tùy thuộc vào một điều kiện được xác định trước. Lưu đồ sau đây cho thấy cấu trúc ra quyết định của Haskell:

Haskell

Haskell cung cấp các loại tuyên bố ra quyết định sau:

Sr.No.Tuyên bố & Mô tả
1câu lệnh if – else Một khi tuyên bố với một người khác tuyên bố. Lệnh trong khối else sẽ chỉ thực thi khi điều kiện Boolean đã cho không thỏa mãn.
2Câu lệnh if-else lồng nhau Nhiều khối if theo sau bởi khối else

Haskell – câu lệnh if-else

Đây là cú pháp chung của việc sử dụng câu lệnh điều kiện if-else trong Haskell.

if<Condition> then <True-Value>else <False-Value>

Trong biểu thức trên,

  • Điều kiện – Đây là điều kiện nhị phân sẽ được kiểm tra.
  • True-Value – Nó đề cập đến kết quả xuất hiện khi Điều kiện thỏa mãn
  • Giá trị sai – Nó đề cập đến kết quả xuất hiện khi điều kiện không thỏa mãn.

Vì mã Haskell được hiểu là các biểu thức toán học, câu lệnh trên sẽ tạo ra một lỗi mà không có khối khác . Đoạn mã sau đây cho thấy cách bạn có thể sử dụng câu lệnh if-else trong Haskell:

main = do   
   let var = 23 
   if var `rem` 2 == 0 
      then putStrLn "Number is Even" 
   else putStrLn "Number is Odd"

Trong ví dụ trên, điều kiện đã cho không thành công. Do đó, khối khác sẽ được thực thi. Nó sẽ tạo ra kết quả sau:

Number is Odd

Haskell – Câu lệnh if-else lồng nhau

Trong ví dụ trên, chúng ta đã thấy việc sử dụng câu lệnh if-else trong Haskell. Ở đây, chúng ta sẽ học cách sử dụng nhiều câu lệnh if-else trong một chương trình Haskell.

Trong Haskell, nhiều dòng if sẽ được sử dụng bằng cách tách từng câu lệnh if với câu lệnh else tương ứng của nó . Đoạn mã sau đây cho thấy cách bạn có thể sử dụng câu lệnh if-else lồng nhau trong Haskell:

main = do   
   let var = 26 
   
   if var == 0 
      then putStrLn "Number is zero" 
   else if var `rem` 2 == 0 
      then putStrLn "Number is Even" 
   else putStrLn "Number is Odd"

Trong ví dụ trên, chúng tôi đã giới thiệu nhiều điều kiện trong một hàm. Tùy thuộc vào các đầu vào chức năng, nó sẽ cung cấp cho chúng ta các đầu ra khác nhau. Bạn có thể thay đổi giá trị của biến “var” để kiểm tra tất cả các điều kiện.

Mã của chúng tôi sẽ tạo ra kết quả sau: Number is Even

Haskell – Types and Type Class (xem thêm)

The post Haskell – Các toán tử cơ bản appeared first on Dongthoigian.

]]>
https://dongthoigian.net/haskell-cac-toan-tu-co-ban/feed/ 0
Haskell – Mô hình dữ liệu cơ bản https://dongthoigian.net/haskell-mo-hinh-du-lieu-co-ban/ https://dongthoigian.net/haskell-mo-hinh-du-lieu-co-ban/#respond Thu, 26 May 2022 08:03:44 +0000 https://dongthoigian.net/?p=13844 chúng ta sẽ tìm hiểu về các mô hình dữ liệu cơ bản của Haskel

The post Haskell – Mô hình dữ liệu cơ bản appeared first on Dongthoigian.

]]>
Haskell là một ngôn ngữ lập trình chức năng thuần túy, do đó nó có tính tương tác và thông minh hơn nhiều so với các ngôn ngữ lập trình khác. Trong chương này, chúng ta sẽ tìm hiểu về các mô hình dữ liệu cơ bản của Haskell thực sự được xác định trước hoặc bằng cách nào đó được giải mã một cách thông minh vào bộ nhớ máy tính.

Trong suốt hướng dẫn này, chúng tôi sẽ sử dụng nền tảng trực tuyến Haskell có sẵn trên trang web của chúng tôi

Con số

Haskell đủ thông minh để giải mã một số nào đó dưới dạng một số. Do đó, bạn không cần phải đề cập đến kiểu của nó ra bên ngoài như chúng ta thường làm trong trường hợp các ngôn ngữ lập trình khác. Theo ví dụ, hãy truy cập dấu nhắc lệnh dạo đầu của bạn và chỉ cần chạy “2 + 2” và nhấn 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

Kết quả là bạn sẽ nhận được kết quả sau.4

Trong đoạn mã trên, chúng tôi chỉ chuyển hai số làm đối số cho trình biên dịch GHCI mà không xác định trước kiểu của chúng, nhưng trình biên dịch có thể dễ dàng giải mã hai mục này dưới dạng số.

Bây giờ, chúng ta hãy thử một phép tính toán học phức tạp hơn một chút và xem liệu trình biên dịch thông minh của chúng ta có cung cấp cho chúng ta kết quả chính xác hay không. Hãy thử với “15+ (5 * 5) -40”

Prelude> 15+(5*5)-40 

Biểu thức trên mang lại “0” theo đầu ra mong đợi. 0

Nhân vật

Giống như các con số, Haskell có thể xác định một cách thông minh một ký tự được đưa vào làm đầu vào cho nó. Đi tới dấu nhắc lệnh Haskell của bạn và nhập bất kỳ ký tự nào có dấu ngoặc kép hoặc dấu nháy đơn.

Hãy để chúng tôi cung cấp dòng sau làm đầu vào và kiểm tra đầu ra của nó.

Prelude> :t "a" 

Nó sẽ tạo ra kết quả sau:

"a" :: [Char] 

Hãy nhớ rằng bạn sử dụng (: t ) trong khi cung cấp đầu vào. Trong ví dụ trên, (: t) là bao gồm loại cụ thể liên quan đến các đầu vào. Chúng ta sẽ tìm hiểu thêm về loại này trong các chương sắp tới. Hãy xem ví dụ sau, nơi chúng tôi đang chuyển một số đầu vào không hợp lệ dưới dạng ký tự, điều này dẫn đến lỗi.

Prelude> :t a 
<interactive>:1:1: Not in scope: 'a'  

Prelude> a 
<interactive>:4:1: Not in scope: 'a' 

Bằng thông báo lỗi “<interactive>: 4: 1: Not in scope:` a ‘”, trình biên dịch Haskell đang cảnh báo chúng tôi rằng nó không thể nhận dạng đầu vào của bạn. Haskell là một loại ngôn ngữ mà mọi thứ được biểu diễn bằng một con số. Haskell tuân theo kiểu mã hóa ASCII thông thường. Chúng ta hãy xem ví dụ sau để hiểu thêm –

Prelude> '\97' 
'a'  
Prelude> '\67' 
'C

Xem cách đầu vào của bạn được giải mã thành định dạng ASCII.

Sợi dây

Một chuỗi không là gì ngoài một tập hợp các ký tự. Không có cú pháp cụ thể để sử dụng chuỗi, nhưng Haskell tuân theo phong cách thông thường là biểu diễn một chuỗi với dấu ngoặc kép.

Hãy xem ví dụ sau, nơi chúng ta đang chuyển chuỗi “dongthoigian.net”.

Prelude> :t " dongthoigian.net " 
Nó sẽ tạo ra kết quả sau trên màn hình:
" dongthoigian.net " :: [Char]
 Xem cách toàn bộ chuỗi đã được giải mã dưới dạng một mảng chỉ Char. Hãy để chúng tôi chuyển sang kiểu dữ liệu khác và cú pháp của nó. Khi chúng tôi bắt đầu thực hành thực tế, chúng tôi sẽ có thói quen với tất cả các loại dữ liệu và việc sử dụng nó.
Boolean
Kiểu dữ liệu Boolean cũng khá đơn giản giống như kiểu dữ liệu khác. Hãy xem ví dụ sau, nơi chúng ta sẽ sử dụng các phép toán Boolean khác nhau bằng cách sử dụng một số đầu vào Boolean như "True" hoặc "False".
Prelude> True && True 
True  
Prelude> True && False 
False   
Prelude> True || True 
True  
Prelude> True || False 
True

Trong ví dụ trên, chúng ta không cần đề cập rằng “True” và “False” là các giá trị Boolean. Bản thân Haskell có thể giải mã nó và thực hiện các thao tác tương ứng. Hãy để chúng tôi sửa đổi đầu vào của chúng tôi bằng “true” hoặc “false”.

Prelude> true 

Nó sẽ tạo ra kết quả sau:

<interactive>:9:1: Not in scope: 'true'

Trong ví dụ trên, Haskell không thể phân biệt giữa giá trị “true” và giá trị số, do đó đầu vào của chúng ta “true” không phải là số. Do đó, trình biên dịch Haskell gặp lỗi cho biết rằng đầu vào của chúng tôi không thuộc phạm vi của nó.

Danh sách và Tổng hợp danh sách

Giống như các kiểu dữ liệu khác, List cũng là một kiểu dữ liệu rất hữu ích được sử dụng trong Haskell. Theo ví dụ, [a, b, c] là một danh sách các ký tự, do đó, theo định nghĩa, Danh sách là một tập hợp có cùng kiểu dữ liệu được phân tách bằng dấu phẩy.

Giống như các kiểu dữ liệu khác, bạn không cần khai báo Danh sách dưới dạng Danh sách. Haskell đủ thông minh để giải mã đầu vào của bạn bằng cách xem cú pháp được sử dụng trong biểu thức. Hãy xem ví dụ sau đây cho thấy cách Haskell xử lý một Danh sách.

Prelude> [1,2,3,4,5] 

Nó sẽ tạo ra kết quả sau:

[1,2,3,4,5] 

Các danh sách trong Haskell có bản chất đồng nhất, có nghĩa là chúng sẽ không cho phép bạn khai báo một danh sách kiểu dữ liệu khác nhau. Bất kỳ danh sách nào như [1,2,3,4,5, a, b, c, d, e, f] sẽ tạo ra lỗi.

Prelude> [1,2,3,4,5,a,b,c,d,e,f] 

Mã này sẽ tạo ra lỗi sau:

<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'

Danh sách hiểu

Hiểu danh sách là quá trình tạo một danh sách bằng cách sử dụng biểu thức toán học. Hãy xem ví dụ sau, nơi chúng ta đang tạo một danh sách bằng cách sử dụng biểu thức toán học ở định dạng [output | phạm vi, điều kiện].

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]

Phương pháp tạo một Danh sách bằng cách sử dụng biểu thức toán học này được gọi là Tổng hợp Danh sách .

Tuple

Haskell cung cấp một cách khác để khai báo nhiều giá trị trong một kiểu dữ liệu duy nhất. Nó được gọi là Tuple . Một Tuple có thể được coi là một Danh sách, tuy nhiên có một số khác biệt về kỹ thuật giữa Tuple và một Danh sách.

Tuple là một kiểu dữ liệu bất biến, vì chúng ta không thể sửa đổi số lượng phần tử trong thời gian chạy, trong khi Danh sách là một kiểu dữ liệu có thể thay đổi.

Mặt khác, Danh sách là một kiểu dữ liệu đồng nhất, nhưng Tuple không đồng nhất về bản chất, bởi vì một Tuple có thể chứa các kiểu dữ liệu khác nhau bên trong nó. Các bộ giá trị được biểu diễn bằng một dấu ngoặc đơn. Hãy xem ví dụ sau để biết cách Haskell đối xử với Tuple.

Prelude> (1,1,'a') 

Nó sẽ tạo ra kết quả sau:

(1,1,'a') 

Trong ví dụ trên, chúng tôi đã sử dụng một tuple với hai số biến loại, và một char loại biến.

Haskell – Các toán tử cơ bản (xem thêm)

The post Haskell – Mô hình dữ liệu cơ bản appeared first on Dongthoigian.

]]>
https://dongthoigian.net/haskell-mo-hinh-du-lieu-co-ban/feed/ 0
Hướng dẫn Haskell https://dongthoigian.net/huong-dan-haskell/ https://dongthoigian.net/huong-dan-haskell/#respond Thu, 26 May 2022 07:53:59 +0000 https://dongthoigian.net/?p=13837 Haskell là một Ngôn ngữ lập trình chức năng được thiết kế đặc biệt để xử lý các ứng dụng tính toán biểu tượng và xử lý danh sách. 

The post Hướng dẫn Haskell appeared first on Dongthoigian.

]]>
Haskell là một ngôn ngữ thuần chức năng được sử dụng rộng rãi. Lập trình hàm dựa trên các hàm toán học. Bên cạnh Haskell, một số ngôn ngữ phổ biến khác tuân theo mô hình lập trình chức năng bao gồm: Lisp, Python, Erlang, Racket, F #, Clojure, v.v. Haskell thông minh hơn các ngôn ngữ lập trình phổ biến khác như Java, C, C ++, PHP, v.v. Trong hướng dẫn này, chúng tôi sẽ thảo luận về các khái niệm và chức năng cơ bản của Haskell bằng cách sử dụng các ví dụ có liên quan để dễ hiểu.

Hướng dẫn này đã được chuẩn bị cho người mới bắt đầu để họ hiểu các khái niệm cơ bản về lập trình hàm sử dụng Haskell làm ngôn ngữ lập trình. Mặc dù đây là hướng dẫn dành cho người mới bắt đầu, chúng tôi giả định rằng người đọc có khả năng tiếp xúc hợp lý với bất kỳ môi trường lập trình nào và có kiến ​​thức về các khái niệm cơ bản như biến, lệnh, cú pháp, v.v.

Haskell – Tổng quan

Haskell là một Ngôn ngữ lập trình chức năng được thiết kế đặc biệt để xử lý các ứng dụng tính toán biểu tượng và xử lý danh sách. Lập trình hàm dựa trên các hàm toán học. Bên cạnh Haskell, một số ngôn ngữ phổ biến khác tuân theo mô hình Lập trình chức năng bao gồm: Lisp, Python, Erlang, Racket, F #, Clojure, v.v.

Trong lập trình thông thường , các lệnh được coi là một tập hợp các khai báo theo một cú pháp hoặc định dạng cụ thể, nhưng trong trường hợp lập trình chức năng , tất cả các phép tính được coi là sự kết hợp của các hàm toán học riêng biệt.

Hoạt động với Haskell

Haskell là một ngôn ngữ thuần chức năng được sử dụng rộng rãi. Ở đây, chúng tôi đã liệt kê ra một vài điểm khiến ngôn ngữ này trở nên đặc biệt so với các ngôn ngữ lập trình thông thường khác như Java, C, C ++, PHP, v.v.

  • Ngôn ngữ chức năng – Trong ngôn ngữ lập trình thông thường, chúng tôi hướng dẫn trình biên dịch một loạt các nhiệm vụ không gì khác ngoài việc cho máy tính của bạn biết “phải làm gì” và “làm như thế nào?” Nhưng trong Haskell, chúng ta sẽ nói với máy tính của mình “nó là gì?”
  • Lười biếng – Haskell là một ngôn ngữ lười biếng. Bởi lười biếng , chúng tôi muốn nói rằng Haskell sẽ không đánh giá bất kỳ biểu hiện nào mà không có lý do. Khi công cụ đánh giá nhận thấy rằng một biểu thức cần được đánh giá, thì nó sẽ tạo một cấu trúc dữ liệu thunk để thu thập tất cả thông tin cần thiết cho đánh giá cụ thể đó và một con trỏ đến cấu trúc dữ liệu thunk đó . Công cụ đánh giá sẽ chỉ bắt đầu hoạt động khi nó được yêu cầu đánh giá biểu hiện cụ thể đó.
  •  – đun – Một ứng dụng Haskell không có gì khác ngoài một loạt các chức năng. Có thể nói rằng một ứng dụng Haskell là một tập hợp của nhiều ứng dụng Haskell nhỏ.
  • Statically Typed – Trong ngôn ngữ lập trình thông thường, chúng ta cần xác định một loạt các biến cùng với kiểu của chúng. Ngược lại, Haskell là một ngôn ngữ được đánh máy nghiêm ngặt. Theo thuật ngữ, ngôn ngữ được nhập đúng, chúng tôi có nghĩa là trình biên dịch Haskell đủ thông minh để tìm ra loại biến được khai báo, do đó chúng tôi không cần đề cập rõ ràng đến loại biến được sử dụng.
  • Khả năng bảo trì – Các ứng dụng Haskell là mô-đun và do đó, rất dễ dàng và tiết kiệm chi phí để duy trì chúng.

Các chương trình chức năng đồng thời hơn và chúng tuân theo song song trong quá trình thực thi để cung cấp hiệu suất chính xác hơn và tốt hơn. Haskell không phải là ngoại lệ; nó đã được phát triển theo cách để xử lý đa luồng một cách hiệu quả.

Chào thế giới

Đó là một ví dụ đơn giản để chứng minh sự năng động của Haskell. Hãy xem đoạn mã sau. Tất cả những gì chúng ta cần chỉ là một dòng để in “Hello Word” trên bảng điều khiển.

main = putStrLn "Hello World"

Khi trình biên dịch Haskell gặp đoạn mã trên, nó sẽ nhanh chóng tạo ra kết quả sau:

Hello World 

Chúng tôi sẽ cung cấp nhiều ví dụ trong suốt hướng dẫn này để giới thiệu sức mạnh và sự đơn giản của Haskell.

Haskell – Thiết lập môi trường

Trình soạn thảo trực tuyến này có rất nhiều tùy chọn để thực hành các ví dụ lập trình Haskell. Đi tới phần đầu cuối của trang và nhập “ghci” . Lệnh này tự động tải trình biên dịch Haskell và khởi động Haskell trực tuyến. Bạn sẽ nhận được kết quả đầu ra sau khi sử dụng lệnh ghci .

sh-4.3$ ghci
GHCi,version7.8.4:http://www.haskell.org/ghc/:?forhelp
Loading package ghc-prim...linking...done.
Loading packageinteger gmp...linking... done.
Loading package base...linking...done.
Prelude>

Nếu bạn vẫn muốn sử dụng Haskell ngoại tuyến trong hệ thống cục bộ của mình, thì bạn cần tải xuống thiết lập Haskell có sẵn từ trang web chính thức của nó – https://www.haskell.org/downloads

Có ba loại trình cài đặt khác nhau có sẵn trên thị trường –

  • Trình cài đặt tối thiểu – Nó cung cấp GHC (Trình biên dịch Glasgow Haskell), CABAL (Kiến trúc chung cho các ứng dụng và thư viện xây dựng), và các công cụ ngăn xếp.
  • Trình cài đặt ngăn xếp – Trong trình cài đặt này, GHC có thể được tải xuống trong một nền tảng chéo của chuỗi thu phí được quản lý. Nó sẽ cài đặt ứng dụng của bạn trên toàn cầu để có thể cập nhật các công cụ API của mình bất cứ khi nào được yêu cầu. Nó tự động giải quyết tất cả các phụ thuộc theo hướng Haskell.
  • Nền tảng Haskell – Đây là cách tốt nhất để cài đặt Haskell vì nó sẽ cài đặt toàn bộ nền tảng trong máy của bạn và từ một vị trí cụ thể. Trình cài đặt này không phân phối như hai trình cài đặt trên.

Chúng tôi đã thấy các loại trình cài đặt khác nhau có sẵn trên thị trường, bây giờ chúng ta hãy xem cách sử dụng các trình cài đặt đó trong máy của chúng tôi. Trong hướng dẫn này, chúng tôi sẽ sử dụng trình cài đặt nền tảng Haskell để cài đặt trình biên dịch Haskell trong hệ thống của chúng tôi.

Môi trường thiết lập trong Windows

Để thiết lập môi trường Haskell trên máy tính Windows của bạn, hãy truy cập trang web chính thức của họ https://www.haskell.org/platform/windows.html và tải xuống Trình cài đặt theo kiến ​​trúc có thể tùy chỉnh của bạn.

Hướng dẫn Haskell

Kiểm tra kiến ​​trúc hệ thống của bạn và tải xuống tệp thiết lập tương ứng và chạy nó. Nó sẽ cài đặt giống như bất kỳ ứng dụng Windows nào khác. Bạn có thể cần cập nhật cấu hình CABAL của hệ thống của mình.

Môi trường thiết lập trong MAC

Để thiết lập môi trường Haskell trên hệ thống MAC của bạn, hãy truy cập trang web chính thức của họ https://www.haskell.org/platform/mac.html và tải xuống trình cài đặt Mac.

Hướng dẫn Haskell

Môi trường thiết lập trong Linux

Cài đặt Haskell trên một hệ thống dựa trên Linux yêu cầu chạy một số lệnh không dễ dàng như MAC và Windows. Vâng, nó là mệt mỏi nhưng nó là đáng tin cậy.

Bạn có thể làm theo các bước dưới đây để cài đặt Haskell trên hệ thống Linux của mình –

Bước 1 – Để thiết lập môi trường Haskell trên hệ thống Linux của bạn, hãy truy cập trang web chính thức https://www.haskell.org/platform/linux.html và chọn bản phân phối của bạn. Bạn sẽ tìm thấy màn hình sau trên trình duyệt của mình.

Hướng dẫn Haskell

Bước 2 – Chọn Phân phối của bạn. Trong trường hợp của chúng tôi, chúng tôi đang sử dụng Ubuntu. Sau khi chọn tùy chọn này, bạn sẽ nhận được trang sau trên màn hình của mình với lệnh cài đặt Haskell trong hệ thống cục bộ của chúng tôi.

Hướng dẫn Haskell

Bước 3 – Mở một thiết bị đầu cuối bằng cách nhấn Ctrl + Alt + T. Chạy lệnh “$ sudo apt-get install haskell-platform” và nhấn Enter. Nó sẽ tự động bắt đầu tải xuống Haskell trên hệ thống của bạn sau khi xác thực bạn bằng mật khẩu gốc. Sau khi cài đặt, bạn sẽ nhận được một thông báo xác nhận.

Bước 4 – Truy cập lại thiết bị đầu cuối của bạn và chạy lệnh GHCI. Khi bạn nhận được lời nhắc Prelude, bạn đã sẵn sàng sử dụng Haskell trên hệ thống cục bộ của mình.

Hướng dẫn Haskell

Để thoát khỏi GHCI prolog, bạn có thể sử dụng lệnh “: thoát khỏi lối ra”

Haskell – Mô hình dữ liệu cơ bản (xem thêm)

The post Hướng dẫn Haskell appeared first on Dongthoigian.

]]>
https://dongthoigian.net/huong-dan-haskell/feed/ 0