Toán tử chấm trong Haskell
Tôi đang cố gắng hiểu toán tử dấu chấm đang làm gì trong mã Haskell này:
sumEuler = sum . (map euler) . mkList
Câu trả lời ngắn
Mã tương đương không có dấu chấm, đó chỉ là
sumEuler = \x -> sum ((map euler) (mkList x))
hoặc không có lambda
sumEuler x = sum ((map euler) (mkList x))
vì dấu chấm (.) biểu thị thành phần chức năng.
Câu trả lời dài hơn
Trước tiên, hãy đơn giản hóa việc áp dụng một phần euler
để map
:
map_euler = map euler
sumEuler = sum . map_euler . mkList
Bây giờ chúng ta chỉ có các dấu chấm. Điều gì được chỉ ra bởi những dấu chấm này?
Từ nguồn :
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
Như vậy (.)
là toán tử soạn thảo .
Soạn, biên soạn
Trong toán học, chúng ta có thể viết thành phần của các hàm, f (x) và g (x), nghĩa là f (g (x)), dưới dạng
(f ∘ g) (x)
có thể đọc là "f soạn với g".
Vì vậy, trong Haskell, f ∘ g, hoặc f được viết bằng g, có thể được viết:
f . g
Thành phần là liên kết, có nghĩa là f (g (h (x))), được viết bằng toán tử thành phần, có thể bỏ ngoặc đơn mà không có bất kỳ sự mơ hồ nào.
Nghĩa là, vì (f ∘ g) ∘ h tương đương với f ∘ (g ∘ h), chúng ta có thể viết đơn giản f ∘ g ∘ h.
Vòng trở lại
Quay trở lại đơn giản hóa trước đó của chúng tôi, điều này:
sumEuler = sum . map_euler . mkList
chỉ có nghĩa là đó sumEuler
là thành phần chưa được áp dụng của các chức năng đó:
sumEuler = \x -> sum (map_euler (mkList x))