Tôi đang viết một CRUD như ứng dụng và có rất nhiều tra cứu bằng khóa chính (khóa chính có thể có các loại khác nhau). Vì vậy, tôi định nghĩa sau typeclass:Inferring Eq typeclass
{-# LANGUAGE MultiParamTypeClasses #-}
class Eq b => HasPK a b where
getPK :: a -> b
Bây giờ tôi có thể viết:
import Data.Maybe
lookupPK :: HasPK a b => b -> [a] -> Maybe a
lookupPK s = listToMaybe . filter ((== s) . getPK)
Bây giờ, khi tôi muốn so sánh hai điều với PK, tôi chỉ muốn so sánh của PK của họ. Vì vậy, tôi đang cố gắng để xác định điều này:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
instance (HasPK a b) => Eq a where
(==) = (==) `on` getPK
Nhưng bây giờ nó mang lại cho tôi:
src/Utils.hs:61:10: Could not deduce (HasPK a b0) …
arising from the ambiguity check for an instance declaration
from the context (HasPK a b)
bound by an instance declaration: HasPK a b => Eq a
at /home/utdemir/workspace/.../Utils.hs:61:10-28
The type variable ‘b0’ is ambiguous
In the ambiguity check for: forall a b. HasPK a b => Eq a
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the instance declaration for ‘Eq a’
Compilation failed.
bất cứ ai có thể giải thích lỗi này với tôi? Tôi đang đi đúng hướng hay có cách nào an toàn hơn để đạt được những gì tôi muốn?
Vâng, sau khi xác định trường hợp đó, tôi đã nhận 'src/Utils.hs: 52: 20: Chồng chéo trường hợp cho số nguyên Eq phát sinh từ việc sử dụng '/ ='… Các trường hợp phù hợp: Ví dụ Eq Số nguyên - Được xác định trong trường hợp ‘số nguyên-gmp: GHC.Integer.Type’ (Eq b, HasPK a b) => Eq a'. Nhưng tôi đã không mong đợi lỗi đó vì 'Integer' không có một phiên bản' HasPk Integer b'. Tôi muốn hiểu lỗi nếu tôi xác định cả hai Eq và HasPK, nhưng vì không có 'HasPK Integer', nên nó không trực tiếp sử dụng cá thể' Eq' bình thường? – utdemir
@utdemir Vấn đề là: một 'instance C a => Eq a' áp dụng cho mọi kiểu, ngay cả với kiểu' C a' là false (!). Haskell sẽ cam kết sử dụng trường hợp này, và khi 'C a' nó sai nó sẽ lỗi, thay vì backtracking và tìm các trường hợp khác. Điều này được thực hiện bởi vì với backtracking vấn đề trở nên khó khăn hơn nhiều, và các nhà thiết kế Haskell đã quan tâm đến thời gian biên dịch.GHC có một phần mở rộng 'OverlappingInstances' để thư giãn hạn chế này, nhưng tôi không khuyến khích nó. Các trường hợp chồng chéo là tốt nhất để tránh, IMHO. – chi
Cảm ơn bạn, tôi đã đi với giải pháp gia đình loại vì nó trông giống như phần mở rộng gây tranh cãi ít nhất là một. – utdemir