我的特殊問題可能與存在類型有關,但我不確定,所以我不會把它放在標題中。理解類型約束
無論如何,這就是我想要做的。
有一個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