我正在写一个类似于应用程序的CRUD,并且主键有很多查找(主键可以有不同的类型).所以我定义了以下类型类:
{-# LANGUAGE MultiParamTypeClasses #-}
class Eq b => HasPK a b where
getPK :: a -> b
Run Code Online (Sandbox Code Playgroud)
现在我可以写:
import Data.Maybe
lookupPK :: HasPK a b => b -> [a] -> Maybe a
lookupPK s = listToMaybe . filter ((== s) . getPK)
Run Code Online (Sandbox Code Playgroud)
现在,当我想用PK比较两件事时,我只想比较他们的PK.所以,我试图定义这个:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
instance (HasPK a b) => Eq a where
(==) = (==) `on` getPK
Run Code Online (Sandbox Code Playgroud)
但现在它给了我:
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.
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释这个错误吗?我是在正确的轨道上,还是有更安全的方式来实现我想要的?
你需要一个功能依赖:使用
class Eq b => HasPK a b | a -> b where
getPK :: a -> b
Run Code Online (Sandbox Code Playgroud)
并启用GHC指向的任何扩展名.
问题在于可能有多个PK用于相同类型,如
instance HasPK MyType Int where ...
instance HasPK MyType String where ...
Run Code Online (Sandbox Code Playgroud)
由于上面的双实例可以在以后添加,因此代码(==) `on` getPK
可能不明确.实际上,当添加上述实例时,它不指定是使用Int
PK还是使用PK String
.
但是,像一个实例
instance (HasPK a b) => Eq a where
...
Run Code Online (Sandbox Code Playgroud)
可能会导致问题,因为它与任何其他Eq
实例重叠.这里要小心.我会改写
equalPK :: HasPK a b => a -> a -> Bool
equalPK = (==) `on` getPK
Run Code Online (Sandbox Code Playgroud)
然后为所有相关类型提供显式实例,如下所示:
instance Eq MyType1 where (==) = equalPK
instance Eq MyType2 where (==) = equalPK
...
Run Code Online (Sandbox Code Playgroud)
作为另一种选择,您可以使用类型系列,例如
class HasPK a where
type PK a
getPK :: a -> PK a
equalPK :: Eq (PK a) => a -> a -> Bool
equalPK = (==) `on` getPK
instance Eq MyType1 where (==) = equalPK
...
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
87 次 |
最近记录: |