Có vẻ như thú vị khi đăng một số câu hỏi làm câu trả lời. Đây là một điều thú vị, về sự tương tác giữa Applicative
và Traversable
, dựa trên sudoku.
(1) Xem xét
data Triple a = Tr a a a
Xây dựng
instance Applicative Triple
instance Traversable Triple
để các dụ Applicative
làm "vector" và dụ Traversable
làm việc trái sang phải. Đừng quên xây dựng một ví dụ phù hợp Functor
: kiểm tra xem bạn có thể trích xuất mẫu này từ một trong các ví dụ Applicative
hoặc Traversable
không. Bạn có thể tìm thấy
hữu ích cho trường hợp sau.
(2) Xem xét
newtype (:.) f g x = Comp {comp :: f (g x)}
Chứng minh rằng
instance (Applicative f, Applicative g) => Applicative (f :. g)
instance (Traversable f, Traversable g) => Traversable (f :. g)
Bây giờ xác định
type Zone = Triple :. Triple
Giả sử chúng tôi đại diện một Board
như một khu vực dọc các khu ngang
type Board = Zone :. Zone
Hiển thị cách sắp xếp lại vị trí đó dưới dạng vùng ngang của các khu vực dọc và làm hình vuông của hình vuông, sử dụng chức năng của traverse
.
(3) Xem xét
newtype Parse x = Parser {parse :: String -> [(x, String)]} deriving Monoid
hoặc một số công trình khác phù hợp (lưu ý rằng hành vi thư viện Monoid
cho | Có lẽ | là không phù hợp).Xây dựng
instance Applicative Parse
instance Alternative Parse -- just follow the `Monoid`
và thực hiện
ch :: (Char -> Bool) -> Parse Char
trong đó tiêu thụ và cung cấp một nhân vật nếu nó được chấp nhận bởi một vị nhất định.
(4) Thực hiện một phân tích cú pháp trong đó tiêu thụ bất kỳ số lượng khoảng trắng, tiếp theo là một chữ số duy nhất (0 đại diện cho khoảng trống)
square :: Parse Int
Sử dụng pure
và traverse
để xây dựng
board :: Parse (Board Int)
(5) Hãy xem xét các functors không đổi
newtype K a x = K {unK :: a}
và constru ct
instance Monoid a => Applicative (K a)
sau đó sử dụng để thực hiện traverse
crush :: (Traversable f, Monoid b) => (a -> b) -> f a -> b
Xây dựng newtype
wrappers cho Bool
thể hiện cấu trúc monoid nối tiếp và rời rạc của nó. Sử dụng crush
để triển khai các phiên bản any
và all
hoạt động với bất kỳ Traversable
functor nào.
(6) Thực hiện
duplicates :: (Traversable f, Eq a) => f a -> [a]
máy tính danh sách các giá trị mà xảy ra nhiều hơn một lần. (Không hoàn toàn tầm thường.) (Có một cách đáng yêu để làm điều này bằng phép tính khác biệt, nhưng đó là một câu chuyện khác.)
(7) Thực hiện
complete :: Board Int -> Bool
ok :: Board Int -> Bool
đó kiểm tra xem một bảng là (1) đầy đủ chỉ các số trong [1..9] và (2) không có các bản sao trong bất kỳ hàng, cột hoặc ô nào.
Tôi không thể đề xuất bài tập, nhưng bạn có thể xem xét các ứng viên không đơn thuần (một câu hỏi quan trọng có vẻ là "tại sao thiết kế một hàm functor khi nó ít mạnh hơn một đơn?"). Ứng dụng đa lỗi (trong Paterson và McBride) là một, cũng có các trình phân tích cú pháp của Doaitse Swierstra, một hoạt ảnh _Active_ trong Andy Gill và Bảng đen của Kevin Matledge và tôi nghĩ rằng Andy Gill và đồng nghiệp của Kansas 'Lava dựa trên một hàm functor. –