hig*_*dth 7 haskell functional-programming instance typeclass
I am trying to represent weighted edges. I eventually want to have OutE to be an instance of Eq and Ord, with the constraint that etype is an instance of Eq and Ord. Assume I have following file as temp.hs:
data (Ord etype)=> OutE vtype etype = OutE {destVertex:: vtype, edgeValue::etype}
applyFunBy accessor ordfun = (\x y -> (ordfun (accessor x) (accessor y)))
instance Eq (OutE vtype etype) where
--(==) :: Ord etype => (OutE vtype etype) -> (OutE vtype etype) -> Bool
--(/=) :: Ord etype => (OutE vtype etype) -> (OutE vtype etype) -> Bool
(==) = applyFunBy edgeValue (==)
(/=) = applyFunBy edgeValue (/=)
Run Code Online (Sandbox Code Playgroud)
when I load this in ghci, I get the following errors:
temp.hs:10:19:
Could not deduce (Ord etype)
from the context (Eq (OutE vtype etype))
arising from a use of `edgeValue' at temp.hs:10:19-27
Possible fix:
add (Ord etype) to the context of the instance declaration
In the first argument of `applyFunBy', namely `edgeValue'
In the expression: applyFunBy edgeValue (==)
In the definition of `==': == = applyFunBy edgeValue (==)
temp.hs:11:19:
Could not deduce (Ord etype)
from the context (Eq (OutE vtype etype))
arising from a use of `edgeValue' at temp.hs:11:19-27
Possible fix:
add (Ord etype) to the context of the instance declaration
In the first argument of `applyFunBy', namely `edgeValue'
In the expression: applyFunBy edgeValue (/=)
In the definition of `/=': /= = applyFunBy edgeValue (/=)
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)
If include the lines for the type signatures for (==) and (\=), I get:
temp.hs:6:1:
Misplaced type signature:
== ::
(Ord etype) => (OutE vtype etype) -> (OutE vtype etype) -> Bool
temp.hs:7:1:
Misplaced type signature:
/= ::
(Ord etype) => (OutE vtype etype) -> (OutE vtype etype) -> Bool
Run Code Online (Sandbox Code Playgroud)
你限制etype是Ord在把定义OutE:
data (Ord etype) => OutE vtype etype = ...
Run Code Online (Sandbox Code Playgroud)
但在Eq实例中,您实际上是在尝试为任何 etype无限制的实例定义实例.
instance Eq (OutE vtype etype) where
Run Code Online (Sandbox Code Playgroud)
当然这不起作用,因为OutE它本身只是为Ord etypes 定义的,因此你也必须将类型类约束添加到实例定义中.
instance (Ord etype) => Eq (OutE vtype etype) where
Run Code Online (Sandbox Code Playgroud)
请注意,一个==或多个定义/=足以使类型类工作.
请注意,它通常更容易,因此被认为是更好的样式,不要在data-types 上有类型类约束,而只是在实际需要类型类功能的实例/方法上.
在许多情况下,一个人不需要约束,最终会得到不必要的笨拙类型签名.
以某些有序地图类型为例Ord key => Map key value.
如果我们只想列出所有密钥怎么办?或者获得元素的数量?我们不需要这些键Ord,所以为什么不简单地让地图不受限制
getKeys :: Map key value -> [key]
getLength :: Map key value -> Int
Run Code Online (Sandbox Code Playgroud)
只需在我们真正需要它的时候添加类型类
insert :: Ord key => key -> value -> Map key value
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4747 次 |
| 最近记录: |