我要定義以下類型類Mapping
:哈斯克爾:類型類問題
{-# LANGUAGE MultiParamTypeClasses #-}
class Mapping k v m where
empty :: m v
insert :: k -> v -> m v -> m v
search :: k -> m v -> Maybe v
delete :: k -> m v -> m v
一個Mapping
實例Data.Map.Map
{-# LANGUAGE ..., FlexibleInstances #-}
instance Ord k => Mapping k v (Map.Map k) where
empty = Map.empty
search = Map.lookup
insert = Map.insert
delete = Map.delete
現在我想創建一個類型Trie :: * -> * -> * -> *
如
{-# LANGUAGE ..., UndecidableInstances #-}
data Trie m k v = Trie {
trValue :: Maybe v,
trChildren :: m (Trie m k v)
}
instance Mapping k (Trie m k v) m => Mapping [k] v (Trie m k) where
search [] tree = trValue tree
search (x:xs) tree =
search xs =<< search x (trChildren tree)
到目前爲止好, 現在我也想定義Trie
的insert
和empty
,這就是我遇到問題的地方。
我將討論empty
,因爲它更簡單和insert
需要它無論如何.. 如果我試試這個:
instance Mapping k (Trie m k v) m => Mapping [k] v (Trie m k) where
empty = Trie { trValue = Nothing, trChildren = empty }
...
,這讓我得到以下錯誤:
Could not deduce (Mapping k (Trie m k1 v) (m k1))
from the context (Mapping [k1] v (Trie m k1),
Mapping k1 (Trie m k1 v) (m k1))
arising from a use of `empty' at test.hs:27:49-53
Possible fix:
add (Mapping k (Trie m k1 v) (m k1)) to the context of
the instance declaration
or add an instance declaration for (Mapping k (Trie m k1 v) (m k1))
In the `trChildren' field of a record
In the expression: Trie {trValue = Nothing, trChildren = empty}
In the definition of `empty':
empty = Trie {trValue = Nothing, trChildren = empty}
我已經嘗試並試圖解決它但失敗。
有誰知道如何使它工作?它甚至有可能嗎?
順便說一句,我建議從類型定義中除去`v`(但將其留在方法的簽名中)。你不需要它,至少對於你迄今爲止給出的所有結構,因爲它們都將採取任何包含的類型,並且它使得一切都變得更簡單。 – 2009-06-19 21:42:53