Một foo miễn phí xảy ra là điều đơn giản nhất thỏa mãn tất cả các luật 'foo'. Đó là để nói rằng nó đáp ứng chính xác các luật cần thiết để trở thành một foo và không có gì thêm.
Một functor hay quên là một phần "quên" một phần cấu trúc khi nó đi từ loại này sang loại khác.
Cho functor F : D -> C
, và G : C -> D
, chúng tôi nói F -| G
, F
được điều chỉnh bên trái G
, hoặc G
là điều chỉnh bên phải cho F
bất cứ khi nào forall a, b: F a -> b
là đẳng cấu với a -> G b
, trong đó các mũi tên đến từ các loại thích hợp.
Chính thức, một functor miễn phí được điều chỉnh lại cho một functor hay quên.
Monoid miễn phí
Chúng ta hãy bắt đầu với một ví dụ đơn giản hơn, monoid miễn phí.
Lấy một monoid, được xác định bởi một số bộ mang T
, hàm nhị phân để trộn một cặp phần tử với nhau f :: T → T → T
và a unit :: T
, sao cho bạn có luật kết hợp và luật định danh : f(unit,x) = x = f(x,unit)
.
Bạn có thể tạo ra một functor U
từ thể loại đơn sắc (trong đó mũi tên là đồng cấu đơn hình, nghĩa là chúng đảm bảo chúng ánh xạ unit
sang unit
đơn hình khác và bạn có thể soạn trước hoặc sau khi ánh xạ sang đơn hình khác mà không thay đổi ý nghĩa) trong số các bộ (trong đó mũi tên chỉ là mũi tên chức năng) 'quên' về hoạt động unit
và chỉ cung cấp cho bạn bộ vận chuyển.
Sau đó, bạn có thể định nghĩa một functor F
từ danh mục các tập hợp trở lại danh mục các đơn âm được điều chỉnh trái với functor này. Functor đó là functor ánh xạ một tập hợp thành a
đơn hình [a]
, ở đâu unit = []
và mappend = (++)
.
Vì vậy, để xem xét ví dụ của chúng tôi cho đến nay, trong pseudo-Haskell:
U : Mon → Set -- is our forgetful functor
U (a,mappend,mempty) = a
F : Set → Mon -- is our free functor
F a = ([a],(++),[])
Sau đó để hiển thị F
là miễn phí, chúng ta cần chứng minh rằng nó được điều chỉnh trái U
, một functor hay quên, nghĩa là, như chúng ta đã đề cập ở trên, chúng ta cần chứng minh rằng
F a → b
đẳng cấu a → U b
Bây giờ, hãy nhớ mục tiêu F
là trong danh mục Mon
đơn chất, trong đó mũi tên là đồng cấu đơn hình, vì vậy chúng ta cần phải chỉ ra rằng một phép đồng hình đơn hình từ [a] → b
có thể được mô tả chính xác bởi một hàm từ a → b
.
Trong Haskell, chúng tôi gọi khía cạnh của cái này sống trong Set
(er, Hask
danh mục các loại Haskell mà chúng tôi giả vờ là Set), chỉ foldMap
, khi chuyên biệt từ Data.Foldable
Danh sách có loại Monoid m => (a → m) → [a] → m
.
Có những hậu quả xảy ra sau đây là một sự điều chỉnh. Đáng chú ý là nếu bạn quên thì hãy xây dựng miễn phí, sau đó quên lại, giống như bạn đã quên một lần và chúng ta có thể sử dụng điều này để xây dựng sự tham gia đơn nguyên. kể từ UFUF
~U(FUF)
~ UF
, và chúng ta có thể chuyển từ trạng thái đồng hình đơn hình nhận dạng từ [a]
sang [a]
qua cấu trúc đẳng cấu xác định điều chỉnh của chúng ta, nhận được rằng một danh sách đẳng cấu từ [a] → [a]
là một hàm của kiểu a -> [a]
và đây chỉ là trả về cho danh sách.
Bạn có thể soạn tất cả những điều này trực tiếp hơn bằng cách mô tả một danh sách theo các thuật ngữ này với:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
Đơn nguyên miễn phí
Vậy cái gì là Monad miễn phí là gì?
Vâng, chúng tôi làm điều tương tự như chúng tôi đã làm trước đây, chúng tôi bắt đầu với một functor U đáng quên từ thể loại đơn nguyên trong đó mũi tên là đồng cấu đơn nguyên đến một thể loại endofunctor trong đó mũi tên là biến đổi tự nhiên, và chúng tôi tìm kiếm một functor bị điều chỉnh trái đến đó
Vì vậy, làm thế nào điều này liên quan đến khái niệm của một đơn nguyên tự do như nó thường được sử dụng?
Biết rằng một cái gì đó là một đơn nguyên miễn phí Free f
, nói với bạn rằng đưa ra một sự đồng hình đơn nguyên từFree f -> m
, cũng giống như việc tạo ra một phép biến đổi tự nhiên (một phép đồng hình functor) từ f -> m
. Hãy nhớ rằng F a -> b
phải là đẳng cấu để a -> U b
F được điều chỉnh trái với U. U ở đây ánh xạ các đơn nguyên cho functor.
F ít nhất là đẳng cấu với Free
loại tôi sử dụng trong free
gói hackage.
Chúng tôi cũng có thể xây dựng nó tương tự chặt chẽ hơn với mã ở trên cho danh sách miễn phí, bằng cách xác định
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Cofree Comonads
Chúng ta có thể xây dựng một cái gì đó tương tự, bằng cách nhìn vào sự điều chỉnh đúng cho một functor hay quên giả sử nó tồn tại. Một functor cofree chỉ đơn giản là / sự điều chỉnh đúng / cho một functor hay quên, và bằng cách đối xứng, biết một cái gì đó là một comonad cofree cũng giống như biết rằng việc đưa ra một phép đồng hình comonad từ đó w -> Cofree f
cũng giống như việc chuyển đổi tự nhiên w -> f
.