Tôi đang phát triển một thư viện xử lý dữ liệu số chuyên ngành và tôi đã gặp một lỗi mà tôi không thể tìm ra cách khắc phục. Tôi nghĩ sẽ dễ dàng hơn để hiển thị một ví dụ trước và sau đó giải thích vấn đề của tôi. Tôi cũng xin lỗi vì những cái tên kỳ lạ, tôi phải làm xáo trộn vì mục đích pháp lý.Giải quyết thể hiện không rõ ràng cho lớp loại multiparam
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
data MyError = MyError String deriving (Eq, Show)
data MyList = MyList [Double] deriving (Eq, Show)
data NamedList = NamedList String MyList deriving (Eq, Show)
class MyNum a b ret where
myAdd :: a -> b -> Either MyError ret
myLessThan :: a -> b -> Either MyError Bool
instance MyNum MyList Double MyList where
myAdd (MyList xs) x = Right $ MyList $ map (+x) xs
myLessThan (MyList xs) x = Right $ all (< x) xs
instance MyNum NamedList Double NamedList where
myAdd (NamedList n l) x = fmap (NamedList n) $ myAdd l x
myLessThan (NamedList n l) x = myLessThan l x
Nếu tôi cố gắng biên dịch này, tôi nhận được lỗi
No instance for (MyNum MyList Double ret0)
arising from a use of `myLessThan'
The type variable `ret0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance MyNum MyList Double MyList
-- Defined at testing_instances.hs:13:10
Possible fix:
add an instance declaration for (MyNum MyList Double ret0)
In the expression: myLessThan l x
In an equation for `myLessThan':
myLessThan (NamedList n l) x = myLessThan l x
In the instance declaration for `MyNum NamedList Double NamedList'
Bởi vì trình biên dịch không thể tìm ra mà cụ thể thể hiện của MyNum
để sử dụng cho MyList
. Nó hoạt động cho myAdd
vì kiểu trả về cho MyNum
có thể dễ dàng bắt nguồn, nhưng nó không thể tìm ra cho myLessThan
. Tôi muốn sử dụng kiểu chữ này để tôi có thể dễ dàng thêm xử lý lỗi chi tiết trong suốt và vì mã thực của tôi có giá trị tương đương là +, -, *, /, <, < =,> và> = và tôi muốn để tạo một phiên bản cho MyNum Double MyList MyList
, MyNum MyList MyList MyList
và các phiên bản tương tự cho NamedList
. Trừ khi có một cách dễ dàng hơn để làm điều này, nó là để tôi có thể có các toán tử giao hoán đa hình.
Tuy nhiên, tôi không thể tìm ra chữ ký loại để thêm vào myLessThan
cho phiên bản thứ hai để có thể biết được cá thể nào cần sử dụng. Tôi biết một giải pháp là chia các toán tử số học và so sánh thành hai loại lớp riêng biệt, nhưng tôi muốn tránh làm như vậy nếu có thể.
Đây là một cấu trúc trước đây không quen thuộc trong Haskell đối với tôi và chính xác những gì tôi cần, cảm ơn! – bheklilr
@bheklilr vui vì tôi có thể giúp. Bạn cũng có thể muốn tìm hiểu về TypeFamilies, dễ dàng hơn để làm việc với một số cách và mạnh mẽ hơn. – jberryman