2012-01-09 25 views
11

Tôi đọc một article mà nói:Chức năng nào bạn nhận được miễn phí với Functors hoặc các loại lớp khác?

Cung cấp các trường hợp cho nhiều kiểu lớp học tiêu chuẩn [functors] sẽ ngay lập tức cung cấp cho bạn rất nhiều chức năng cho thực tế miễn phí

Câu hỏi của tôi là: những gì là chức năng này mà bạn nhận được miễn phí (cho functors hoặc loại lớp khác)? Tôi biết định nghĩa của một functor là gì, nhưng tôi phải làm gì cho miễn phí bằng cách xác định một cái gì đó như một functor/loại lớp khác. Một cái gì đó khác hơn là một cú pháp đẹp hơn. Lý tưởng nhất đây sẽ là các hàm tổng quát và hữu ích hoạt động trên các hàm/các lớp kiểu khác.

trí tưởng tượng của tôi (có thể là sai) về những gì có nghĩa là miễn phí là chức năng của loại này: TypeClass x => useful x y = ..

== Sửa/Additition ==

Tôi đoán tôi chủ yếu hỏi về trừu tượng hơn (và não boggling) loại-lớp học, giống như những người trong this image. Đối với các lớp trừu tượng ít hơn như Ord, trực giác hướng đối tượng của tôi hiểu được.

Trả lời

9

Functors rất đơn giản và có lẽ không phải là ví dụ tốt nhất. Chúng ta hãy nhìn vào Monads thay vì:

  • liftM - nếu có điều gì là một đơn nguyên, nó cũng là một functor nơi liftMfmap.
  • >=>, <=<: bạn có thể soạn các hàm a -> m b miễn phí trong đó m là đơn vị của bạn.
  • foldM, mapM, filterM ... bạn nhận được một loạt các chức năng tiện ích tổng quát hóa các chức năng hiện có để sử dụng đơn nguyên của bạn.
  • when, guard * và unless - bạn cũng nhận được một số chức năng điều khiển miễn phí.
  • join - điều này thực sự khá cơ bản đối với định nghĩa của một đơn nguyên, nhưng bạn không cần phải xác định nó trong Haskell vì bạn đã xác định >>=.
  • máy biến áp - ErrorT và nội dung. Bạn có thể xử lý lỗi bolt vào loại mới của mình, miễn phí (tặng hoặc lấy)!

Về cơ bản, bạn nhận được nhiều chức năng tiêu chuẩn "dỡ bỏ" để sử dụng loại mới của bạn ngay sau khi bạn tạo một phiên bản Monad. Nó cũng trở nên tầm thường (nhưng không phải là tự động) để biến nó thành FunctorApplicative.

Tuy nhiên, đây là tất cả "các triệu chứng" của một ý tưởng chung chung hơn. Bạn có thể viết mã thú vị, không đặc biệt áp dụng cho tất cả monads. Bạn có thể tìm thấy một số chức năng bạn đã viết cho loại của bạn - đó là hữu ích trong trường hợp cụ thể của bạn, vì bất kỳ lý do gì - có thể được khái quát hóa cho tất cả các monads. Bây giờ bạn có thể đột nhiên lấy chức năng của bạn và sử dụng nó trên phân tích cú pháp, danh sách, và maybes và ...

* Như Daniel Fischer đã chỉ ra một cách hữu ích, guard yêu cầu MonadPlus thay vì Monad.

+5

'bảo vệ' yêu cầu 'MonadPlus'. –

+0

@DanielFischer: Rất tiếc. Điểm tốt. –

+0

Vì dường như chỉ có một số ít các chức năng thư viện như vậy, ngay cả đối với đơn nguyên vốn là một loại lớp khá phong phú, tôi đã kết luận rằng nó không có khả năng xảy ra. Đó là _theoretically_ có thể là mã của bạn có thể tổng quát một cách kỳ diệu cho tất cả các monads, nhưng thực tế nếu chúng tồn tại, tôi sẽ thấy rất nhiều chức năng hữu ích hơn cho các monads. – user1138184

4

Có nhiều hàm chuẩn trong haskell yêu cầu đối số của chúng triển khai một hoặc nhiều loại lớp. Làm như vậy trong mã của bạn cho phép các nhà phát triển khác (hoặc chính bạn) sử dụng dữ liệu của bạn theo cách mà họ đã quen thuộc, mà không cần phải viết các chức năng bổ sung.

Ví dụ: triển khai loại loại Ord sẽ cho phép bạn sử dụng những thứ như sắp xếp, tối thiểu, tối đa, v.v. Nếu không, bạn sẽ cần sortBy và các loại tương tự.

4

Có, điều đó có nghĩa là việc triển khai loại lớp Foo sẽ cung cấp cho bạn tất cả các chức năng khác có hạn chế Foo "miễn phí".

Lớp loại Functor không quá thú vị về mặt đó vì nó không cung cấp cho bạn nhiều.

Ví dụ tốt hơn là monads và các chức năng trong mô-đun Control.Monad. Khi bạn đã xác định hai chức năng Monad(>>=)return cho loại của mình, bạn sẽ nhận được ba mươi hàm khác để có thể sử dụng cho loại của mình.

Một số trong những người hữu ích hơn bao gồm: mapM, sequence, forever, join, foldM, filterM, replicateM, when, unlessliftM. Chúng hiển thị mọi lúc trong mã Haskell.

5

Functors không phải là rất thú vị của mình, nhưng họ là một bước đệm cần thiết để có được vào functors ứng dụng và Traversables.

Thuộc tính chính làm cho các nhà ứng dụng hữu ích là bạn có thể sử dụng fmap với nhà điều hành ứng dụng <*> để "nâng" bất kỳ chức năng nào của bất kỳ hành động nào để làm việc với các giá trị ứng dụng. I E. bạn có thể biến bất kỳ a -> b -> c -> d thành Applicative f => f a -> f b -> f c -> f d. Bạn cũng có thể xem Data.TraversableData.Foldable trong đó có một số chức năng mục đích chung liên quan đến functors ứng dụng.

Alternative là một ứng dụng chuyên biệt functor hỗ trợ lựa chọn giữa các lựa chọn thay thế có thể "thất bại" (ý nghĩa chính xác của "trống" phụ thuộc vào trường hợp ứng dụng). Trình phân tích cú pháp ứng dụng là một ví dụ thực tế trong đó các định nghĩa của somemany rất trực quan (ví dụ: khớp một số mẫu không hoặc nhiều lần hoặc một hoặc nhiều lần).

Monads là một trong những loại lớp học thú vị và hữu ích nhất, nhưng chúng đã được bao phủ bởi các câu trả lời khác.

Monoid là loại lớp khác vừa đơn giản vừa hữu ích. Về cơ bản nó định nghĩa một cách để thêm hai phần dữ liệu với nhau, sau đó cung cấp cho bạn concat chung cũng như chức năng trong mô-đun Foldable nói trên và nó cũng cho phép bạn sử dụng đơn lẻ Writer với kiểu dữ liệu.

2

Như những người khác đã nói, Functor chính nó không thực sự giúp bạn có được nhiều miễn phí. Về cơ bản, một typeclass cao cấp hơn hoặc chung là (nghĩa là nhiều thứ phù hợp với mô tả đó), thì chức năng "miễn phí" ít hơn bạn sẽ nhận được. Vì vậy, ví dụ, Functor, và Monoid không cung cấp cho bạn nhiều, nhưng Monad và Arrow cung cấp cho bạn rất nhiều chức năng hữu ích miễn phí.Trong Haskell, bạn nên viết một thể hiện cho Functor và Monoid (nếu kiểu dữ liệu của bạn thực sự là một functor hoặc monoid), bởi vì chúng ta hầu như luôn cố gắng sử dụng giao diện chung nhất có thể khi viết các hàm . Nếu bạn đang viết một hàm mới có thể lấy đi chỉ bằng cách sử dụng fmap để hoạt động trên loại dữ liệu của bạn, thì không có lý do nào để hạn chế chức năng đó thành Monad s hoặc Applicative s, vì nó có thể hữu ích sau này cho những thứ khác.

1

Trực giác hướng đối tượng của bạn mang theo, nếu bạn đọc "giao diện và triển khai" cho "kiểu chữ và ví dụ". Nếu bạn thực hiện bạn loại C mới một thể hiện của một typeclass B tiêu chuẩn, sau đó bạn sẽ có được miễn phí kiểu của bạn sẽ làm việc với tất cả các mã hiện có Một mà phụ thuộc vào B.

UML diagram

Như những người khác đã nói, khi typeclass là một cái gì đó giống như Monad, sau đó freebies là nhiều chức năng thư viện như foldMwhen.

Các vấn đề liên quan