# Functor: Từ Toán Học Đến Lập Trình Hàm ## 1. Mở đầu Nếu bạn từng lập trình với `List.map` hay `Option.map` trong OCaml, bạn đã dùng **functor** mà có khi chưa nhận ra. Nhưng functor không chỉ là một tiện ích lập trình: nó bắt nguồn từ **category theory** trong toán học — một lĩnh vực trừu tượng nghiên cứu “cấu trúc” và “liên kết giữa các cấu trúc”. Bài viết này sẽ đi từ định nghĩa trong toán học, qua cách hiểu trong lập trình hàm, rồi minh họa bằng ví dụ thực tế. ```mermaid flowchart LR subgraph H2[Category Hask] A2([int]) -- "f : int -> string" --> B2([string]) end subgraph L[List functor] AL([int list]) -- "List.map f : int list -> string list" --> BL([string list]) end A2 -. "F maps objects" .-> AL B2 -. "F maps objects" .-> BL ``` --- ## 2. Category Theory và Functor ### Category là gì? Một **category** bao gồm: - **Objects** – thường nghĩ như các tập hợp hoặc kiểu dữ liệu. - **Morphisms** – ánh xạ (hàm) giữa các đối tượng. Kèm theo 2 quy tắc: - **Identity**: mỗi đối tượng có một mũi tên đơn vị `id`. - **Associativity**: hợp thành các morphism tuân thủ tính kết hợp. Ví dụ: - Category `Set`: objects là tập hợp, morphisms là hàm. - Category `Int`: objects là kiểu số nguyên, morphisms là các hàm `int -> int`. ### Functor trong toán học Một **functor** là ánh xạ giữa hai category `C` và `D` sao cho: - Với mỗi object `A` trong `C`, có `F(A)` trong `D` - Với mỗi morphism `f : A → B`, có `F(f) : F(A) → F(B)` - Và phải thỏa: - `F(id_A) = id_{F(A)}` - `F(f ∘ g) = F(f) ∘ F(g)` => Functor bảo toàn cấu trúc của category. ![ChatGPT Image Sep 23, 2025, 04_37_18 PM](https://hackmd.io/_uploads/Hk4Wsyl3xe.png) --- ## 3. Functor trong Lập Trình Hàm Trong OCaml, một functor là một **type constructor** (kiểu tham số hóa) có thể "ánh xạ hàm" thông qua `map`. `map : ('a -> 'b) -> 'a t -> 'b t` Nó biến một hàm bình thường thành một hàm “trong bối cảnh”. ### Ví dụ: Option ```ocaml let map_option f = function | None -> None | Some x -> Some (f x) ``` Kiểm tra luật functor: ```ocaml let id x = x map_option id (Some 7) = Some 7 (* identity *) map_option (succ ∘ double) (Some 3) = map_option succ (map_option double (Some 3)) (* composition *) ``` ### Ví dụ: List ```ocaml let map_list f lst = List.map f lst ``` ```ocaml map_list id [1;2;3] = [1;2;3] (* identity *) map_list (succ ∘ double) [1;2;3] = map_list succ (map_list double [1;2;3]) (* composition *) ``` --- ## 4. Ý Nghĩa Thực Tế Functor giúp xử lý dữ liệu "bên trong container" (option, list, result...) mà không phải viết lại logic lặp đi lặp lại. Ví dụ: ```ocaml map_option String.uppercase_ascii (Some "hello") (* -> Some "HELLO" *) List.map succ [1;2;3] (* -> [2;3;4] *) ``` Dùng functor giúp code: - Ngắn hơn - Tổng quát hơn - Dễ kết hợp (compose) --- ## 5. Từ Functor đến Các Khái Niệm Nâng Cao Functor là nền tảng cho nhiều khái niệm khác trong lập trình hàm: - **Applicative**: cho phép áp dụng hàm có nhiều tham số trong bối cảnh - **Monad**: cho phép xâu chuỗi logic có phụ thuộc - **Natural Transformation**: biến đổi tự nhiên giữa 2 functor Ví dụ: ```ocaml List.hd_opt : 'a list -> 'a option ``` là một natural transformation từ `list` sang `option`. --- ## 6. Kết luận Functor là chiếc cầu nối giữa toán học trừu tượng và lập trình hiện đại. - Trong **toán học**: functor là ánh xạ giữa các category, giữ nguyên cấu trúc. - Trong **lập trình hàm**: functor là các kiểu có thể “ánh xạ hàm” như `option`, `list`, `result`. Hiểu và sử dụng functor giúp bạn viết code rõ ràng, linh hoạt, và mở đường tiếp cận các khái niệm cao hơn như `applicative` và `monad`. ---