2017-07-27 18 views
5

Hãy xem xét các định nghĩa sau đây cho cây nhị phân:Thực hiện một O (log n) Foldable.elem cho cây tìm kiếm nhị phân trong Haskell

data Tree a = Nil | Node (Tree a) a (Tree a) 

Các dụ Foldable thể được định nghĩa như sau:

instance Foldable Tree where 
    foldr _ z Nil = z 
    foldr f z (Node l d r) = foldr f (f d (foldr f z l)) r 

Nhưng vấn đề là chức năng elem chạy trong O(n) thay vì O(log n). Khi tôi cố gắng thực hiện một phong tục elem:

elem x Nil = False 
elem x (Node l d r) 
    | x == d = True 
    | x < d = elem x l 
    | otherwise = elem x r 

tôi nhận được Could not deduce (Ord a) arising from a use of ‘<’. Làm cách nào để khắc phục sự cố này?

+0

Đối với giá trị của nó: Hàm tương ứng trong 'mono-traversable' là [' oelem'] (https://hackage.haskell.org/package/mono-traversable-1.0.5.0/docs/Data-MonoTraversable. html # v: oelem), và kể từ phiên bản 1.0.5.0, nó có triển khai hiệu quả cho 'Set'. –

Trả lời

4

Bạn không thể sử dụng phương thức elem này cho lớp Có thể gập lại vì API có thể gập lại yêu cầu triển khai elem cho tất cả các trường hợp của nó. "An elem có tính đa hình cho tất cả Eq" là một sự lựa chọn có chủ ý trong thiết kế của kiểu chữ Foldable.

Chức năng elem của bạn, trong khi rất hữu ích, không tương thích với phương pháp elem cho kiểu chữ Foldable, vì nó không phải là đủ chung cho mong muốn của typeclass. Cách tốt nhất để xuất hàm elem cho loại của bạn là xác định một hàm riêng biệt bên ngoài typeclass.

+1

Tôi tự hỏi nếu bạn có thể sử dụng một pragma chuyên để cung cấp một thực hiện hiệu quả hơn cho Ord trường hợp – SwiftsNamesake

+3

@SwiftsNamesake, 'SPECIALIZE' không phải là đủ mạnh thuốc. Bạn cần 'RULES' và bạn cần một quy tắc viết lại * cho mỗi loại *. Thật kinh khủng. – dfeuer

+0

@dfeuer Được nói như một người đàn ông đã đến địa ngục và quay trở lại. Tôi tự hỏi liệu có ai trong nhóm GHC đang làm việc về vấn đề này không. – SwiftsNamesake

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