Tôi đang thực hiện triển khai HList và tôi đang cố gắng triển khai hàm map
cho nó. Tôi đã thử nhiều cách tiếp cận khác nhau nhưng với mỗi phương pháp tôi gặp phải lỗi trình biên dịch liên quan đến hàm đó.Lập bản đồ qua cấu trúc dữ liệu không đồng nhất với chức năng chung
Sau đây là ví dụ về cách tôi muốn sử dụng hàm chung Just
để áp dụng cho tất cả các phần tử của cấu trúc dữ liệu đầu vào.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
-- | An input heterogenous data structure
recursivePairs :: (Int, (Char, (Bool,())))
recursivePairs = (1, ('a', (True,())))
-- | This is how I want to use it
recursivePairs' :: (Maybe Int, (Maybe Char, (Maybe Bool,())))
recursivePairs' = hMap Just recursivePairs
class HMap f input output where
hMap :: f -> input -> output
-- | A counterpart of a Nil pattern match for a list
instance HMap f()() where
hMap _ _ =()
-- | A counterpart of a Cons pattern match for a list
instance
(HMap f iTail oTail,
Apply f iHead oHead) =>
HMap f (iHead, iTail) (oHead, oTail)
where
hMap f (head, tail) = (apply f head, hMap f tail)
class Apply f input output where
apply :: f -> input -> output
instance Apply (input -> output) input output where
apply = id
Với điều này tôi nhận ra lỗi biên dịch sau:
No instance for (Apply (a0 -> Maybe a0) Int (Maybe Int))
arising from a use of `hMap'
The type variable `a0' is ambiguous
Có ở tất cả một cách để giải quyết việc này và nếu không thì tại sao?
Tôi nghĩ vấn đề là hệ thống kiểu không nhận ra rằng bạn đang khởi tạo 'Chỉ với các loại bê tông khác nhau trên mỗi ứng dụng kế tiếp vì định nghĩa' hMap' tiếp tục sử dụng lại 'f'. Lần đầu tiên bạn áp dụng kiểu này là 'Int -> Maybe Int', lần thứ hai bạn áp dụng kiểu này là' Char -> Maybe Char'. Tuy nhiên, tôi vẫn không hoàn toàn chắc chắn làm thế nào để sửa chữa nó. –
@GabrielGonzalez Vâng, đó chính là vấn đề. Và nếu bạn thêm một fundep '| đầu vào đầu vào -> f' vào lớp 'Áp dụng', các thông báo lỗi sẽ nói rằng nó đang tìm kiếm các cá thể, như' (Bool -> Có thể Bool) Char (Có thể Char) '. Tôi đã suy nghĩ về việc sử dụng ['cast'] (http: //hackage.haskell.org/packages/archive/base/mới nhất/doc/html/Data-Typeable.html # v: cast) để ngắt kết nối hai tập quán 'f' trên một loại cấp, nhưng điều đó không cảm thấy rất tự nhiên, và tùy thuộc vào 'Typeable' cũng không hấp dẫn lắm. –