我的特殊问题可能与存在类型有关,但我不确定,所以我不会把它放在标题中。理解类型约束
无论如何,这就是我想要做的。
有一个Entity
类型,它包装在一个异构的组件列表上。然后,我有一个HasComponent a b
类型类别,表示b
列表中包含a
类型的组件。以下是我编写它的方式和类实例。
data Entity c = Entity c
data CompNode c n = CompNode c n
data CompEnd = CompEnd
class HasComponent a b where
getComponent :: b -> a
instance HasComponent a (CompNode a n) where
getComponent (CompNode a _) = a
instance HasComponent a n => HasComponent a (CompNode b n) where
getComponent (CompNode _ n) = getComponent n
instance HasComponent a b => HasComponent a (Entity b) where
getComponent (Entity b) = getComponent b
还有为Entity
一个HasComponent
实例。这只是为了方便。
到目前为止,一切都在编译。
现在,我想尝试一下。我制作了一个DisplayData a
类型,其中包含一些类型为a
的数据,用于显示。这是组件之一。然后,我制作了Displayer a
,它是a -> IO()
类型函数的包装。该组件旨在提供一种显示数据的方式。
data DisplayData a = DisplayData a
data Displayer a = Displayer (a -> IO())
现在,这两个组件应该很好地结合在一起。我想写一个函数display
,它需要一个满足一些约束条件的Entity
并显示它。
这是我尝试
display :: (HasComponent (DisplayData a) c, HasComponent (Displayer a) c) => Entity c -> IO()
display e = f a
where Displayer f = getComponent e :: Displayer a
DisplayData a = getComponent e :: DisplayData a
我想这是什么意思是:“如果存在某种类型,使得(HasComponent (DisplayData a) c, HasComponent (Displayer a) c)
是真的,那么display
可以采取Entity c
并产生一个IO动作。”
我认为,这可能意味着的却是:“如果(HasComponent (DisplayData a) c, HasComponent (Displayer a) c)
为任何和所有类型的真,那么display
可以采取Entity c
并产生一个IO动作
我得到的错误是这个
。 ?Could not deduce (HasComponent (DisplayData a0) c)
arising from the ambiguity check for `display'
from the context (HasComponent (DisplayData a) c,
HasComponent (Displayer a) c)
bound by the type signature for
display :: (HasComponent (DisplayData a) c,
HasComponent (Displayer a) c) =>
Entity c -> IO()
at Components.hs:24:12-94
The type variable `a0' is ambiguous
In the ambiguity check for:
forall c a.
(HasComponent (DisplayData a) c, HasComponent (Displayer a) c) =>
Entity c -> IO()
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for `display':
display :: (HasComponent (DisplayData a) c,
HasComponent (Displayer a) c) =>
Entity c -> IO()
我怎么做我想在这里
是否有任何我应该知道的功能依赖的副作用? – 2014-12-02 09:59:07
您可以编写的一组实例较小。功能依赖本身没有任何其他副作用。为了使函数依赖对你的实例起作用,你需要UndecidableInstances,它有副作用,你可以在类型检查器中有非终结符。对于您的具体情况,不终止将不会发生。 – user2407038 2014-12-02 14:51:24