Tôi tự hỏi liệu có cách tổng quát để chuyển đổi giữa các hàm đa hình ad-hoc và các hàm đa hình tham số hay không. Nói cách khác, được đưa ra một chức năng đa hình ad-hoc, làm thế nào để thực hiện đối số tham số của nó? và còn cách nào khác?cách tốt để chuyển đổi giữa các hàm đa hình ad-hoc và các đa hình tham số
chụp sort
làm ví dụ. thật dễ dàng để viết sort :: Ord a => [a] -> [a]
về sortBy
:
sort :: Ord a => [a] -> [a]
sort = sortBy compare
nhưng cách khác xung quanh dường như khó khăn, cho đến nay là tốt nhất tôi có thể làm là để đi một chút "hướng đối tượng":
import qualified Data.List as L
data OrdVal a = OV (a -> a -> Ordering) a
instance Eq (OrdVal a) where
(OV cmp a) == (OV _ b) = a `cmp` b == EQ
instance Ord (OrdVal a) where
(OV cmp a) `compare` (OV _ b) = a `cmp` b
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
sortBy cmp = map unOV . L.sort . map (OV cmp)
where
unOV (OV _ v) = v
Nhưng điều này nghe có vẻ giống như một hack hơn là giải pháp thích hợp.
vì vậy tôi muốn biết:
- đang có những cách tốt hơn ví dụ cụ thể này?
- các kỹ thuật chung để chuyển đổi giữa các hàm đa hình ad-hoc và các hàm tham số là gì?
Nếu chúng tôi có thể chuyển từ điển (ví dụ như trong Agda implicits), điều này sẽ không quan trọng. Tuy nhiên, tôi tin rằng một số lớp/thư viện khai thác thực tế là chúng tôi không thể chuyển từ điển để đảm bảo một số bất biến. Ví dụ, hãy tưởng tượng nếu chúng ta có thể gọi'Data.Set.insert' bằng cách đặt hàng khác nhau ... – chi
Cũng lưu ý rằng "hack" của bạn hoạt động trong thực tế, nhưng chỉ khi bạn không bao giờ đóng gói hai hàm 'cmp' riêng biệt trong' OrdVal a' values. Nếu bạn làm thế, thì cá thể 'Ord' của bạn không thỏa mãn luật' Ord'. – chi