Banana split và fusion trong lập trình chức năng là gì?


22

Những điều khoản đã được đề cập trong khóa học đại học của tôi. Googling nhanh chóng chỉ cho tôi một số bài báo của trường đại học, nhưng tôi đang tìm kiếm một lời giải thích đơn giản.


@jozefg: Cảm ơn đã liên kết đến bài viết của bạn. Một câu hỏi về nó. Trong câu "Một đại số theo nghĩa này là một cặp đối tượng C và bản đồ FC → C.", C có thực sự được coi là một đối tượng, hay đúng hơn là một thể loại? Nói cách khác, tôi không chắc chắn nếu F biểu thị một functor trong một thể loại và F-algebras là đại số được tạo ra bởi functor đó, nếu F là một mũi tên cụ thể từ một đối tượng vào chính nó.
Giorgio

Clà một đối tượng trong một số loại (giả sử CC), Flà một functor từ CC -> CCđó nó ánh xạ CCtrở lại chính nó. Bây giờ F CC -> CCchỉ là một mũi tên bình thường trong thể loại CC. Vì vậy, Fđại số là một đối tượng C : CCvà một mũi tên F C -> CtrongCC
Daniel Gratzer

Câu trả lời:


4

Mặc dù đã có 2 câu trả lời, tôi không nghĩ rằng "tách chuối" đã được giải thích ở đây.

Nó thực sự được định nghĩa trong "Lập trình chức năng với Chuối, Ống kính, Phong bì và Dây thép gai, Erik Meijer Maarten Fokkinga, Ross Paterson, 1991"; bài báo đó rất khó đọc (đối với tôi) do sử dụng Squiggol rất nhiều. Tuy nhiên, "Hướng dẫn về tính phổ quát và tính biểu cảm của nếp gấp, Graham Hutton, 1999" chứa một định nghĩa dễ phân tích hơn:

Như một ví dụ đơn giản đầu tiên của việc sử dụng lần để tạo ra các bộ, xem xét các chức năng sumlength cho phép tính tổngchiều dài của một danh sách các số:

sumlength :: [Int] → (Int,Int)
sumlength xs = (sum xs, length xs)

Bởi sự kết hợp đơn giản của các định nghĩa của các chức năng tổng hợpchiều dài bằng cách sử dụng lần cho trước, hàm sumlength có thể được định nghĩa lại như một ứng dụng duy nhất của gấp mà tạo ra một cặp số từ một danh sách các số:

sumlength = fold (λn (x, y) → (n + x, 1 + y)) (0, 0)

Định nghĩa này hiệu quả hơn định nghĩa ban đầu, bởi vì nó chỉ thực hiện một lần duyệt qua danh sách đối số, thay vì hai lần duyệt riêng biệt. Generalising từ ví dụ này, bất kỳ cặp của các ứng dụng của lần vào cùng một danh sách luôn có thể được kết hợp để cung cấp cho một ứng dụng duy nhất của gấp mà tạo ra một cặp, bằng cách kêu gọi những cái gọi là 'chuối chẻ' tài sản của lần (Meijer, 1992) . Tên lạ của thuộc tính này xuất phát từ thực tế là toán tử gấp đôi khi được viết bằng dấu ngoặc (| |) giống với chuối và toán tử ghép đôi đôi khi được gọi là tách. Do đó, sự kết hợp của chúng có thể được gọi là tách chuối!


19

Vì vậy, đây thực sự là một tài liệu được tham khảo bởi Meijer và một vài người khác gọi là " Lập trình chức năng với Chuối, Ống kính, Phong bì và Dây thép gai ", ý tưởng cơ bản là chúng ta có thể lấy bất kỳ loại dữ liệu đệ quy nào, như nói

 data List = Cons Int List | Nil

và chúng ta có thể tính ra đệ quy thành một biến kiểu

 data ListF a = Cons Int a | Nil

lý do tại sao tôi nối thêm đó Flà bởi vì đây là một functor! Nó cũng cho phép chúng ta bắt chước các danh sách, nhưng với một nút thắt: để xây dựng danh sách, chúng ta phải lồng loại danh sách

type ThreeList = ListF (ListF (ListF Void)))

Để khôi phục danh sách ban đầu của chúng tôi, chúng tôi cần phải tiếp tục làm tổ này vô cùng . Điều đó sẽ cho chúng ta một loại ListFFnơi

  ListF ListFF == ListFF

Để làm điều này xác định một "loại điểm cố định"

  data Fix f = Fix {unfix :: f (Fix f)}
  type ListFF = Fix ListF

Như một bài tập, bạn nên xác minh điều này thỏa mãn phương trình trên của chúng tôi. Bây giờ chúng ta cuối cùng có thể định nghĩa chuối là gì (dị hình)!

  type ListAlg a = ListF a -> a

ListAlgs là loại "danh sách đại số" và chúng ta có thể định nghĩa một hàm cụ thể

  cata :: ListAlg a -> ListFF -> a
  cata f = f . fmap (cata f) . unfix

Hơn nữa

  cata :: ListAlg a -> ListFF -> a
  cata :: (Either () (Int, a) -> a) -> ListFF -> a
  cata :: (() -> a) -> ((Int, a) -> a) -> ListFF -> a
  cata :: a -> (Int -> a -> a) -> ListFF -> a
  cata :: (Int -> a -> a) -> a -> [Int] -> a

Nhìn có quen không? catachính xác giống như nếp gấp bên phải!

Điều thực sự thú vị là chúng ta có thể làm điều này hơn là chỉ liệt kê, bất kỳ loại nào được xác định bằng "điểm cố định" này đều có catavà để chứa tất cả chúng ta chỉ cần thư giãn chữ ký loại

  cata :: (f a -> a) -> Fix f -> a

Điều này thực sự được lấy cảm hứng từ một phần của lý thuyết thể loại mà tôi đã viết , nhưng đây là phần thịt của phía Haskell.


2
điều đáng nói là chuối là dấu ngoặc (| |) mà bài báo gốc sử dụng để định nghĩa cata
jk.

7

Mặc dù jozefg cung cấp một câu trả lời, tôi không chắc liệu nó có trả lời được câu hỏi không. "Luật hợp nhất" được giải thích trong bài báo sau:

Hướng dẫn về tính phổ quát và tính biểu cảm của nếp gấp, GRAHAM HUTTON, 1999

Về cơ bản nó nói rằng trong một số điều kiện, bạn có thể kết hợp ("cầu chì") thành phần của hàm và gấp thành một nếp gấp, vì vậy về cơ bản

h · gấp gw = gấp fv

Các điều kiện cho sự bình đẳng này là

hw = v
h (gxy) = fx (hy)

"Chẻ chuối" hay "luật chẻ chuối" là từ bài viết

Lập trình chức năng với Chuối, Ống kính, Phong bì và Dây thép gai, Erik Meijer Maarten Fokkinga, Ross Paterson, 1991

Thật không may, bài viết này rất khó để giải mã vì nó sử dụng hình thức chính thức Bird Bird Meertens nên tôi không thể tạo ra đầu hoặc đuôi của nó. Theo như tôi hiểu về "luật phân chia chuối" thì nó nói rằng nếu bạn có 2 lần hoạt động trên cùng một đối số, chúng có thể được hợp nhất thành một lần duy nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.