正确获取Tries的类型声明

时间:2012-12-03 21:39:24

标签: haskell type-inference type-declaration

我正在使用list-tries package

import qualified Data.ListTrie.Patricia.Map as TM
import qualified Data.ListTrie.Patricia.Set as TS
import qualified Data.Map as Map

我有一个字符串列表,我想将它存储在由Trie-Sets组成的Trie-Map中,如下所示:

-- vocabs :: [String]
trie = TM.fromListWith' (flip TS.union) $ map (\v->(sort v, TS.singleton v)) vocabs

(这是为了在外部特里查找一组字母,然后在生成的特里查找特定的字母组合)。

我可以理解Haskell不知道trie具有哪种确切类型,因为我无处指定要使用哪种类型的map。我想我可以通过添加声明

来做到这一点
trie :: TM.TrieMap Map.Map Char (TS.TrieSet Map.Map Char)

但似乎还不够。我仍然收到像

这样的错误消息
  

(Data.ListTrie.Base.Map.Map Map.Map Char)没有实例        使用TrieM.fromListWith'

引起的      

可能的解决方法:        为...添加实例声明        (Data.ListTrie.Base.Map.Map Map.Map Char)

     

在表达式中:TrieM.fromListWith' TrieS.union

     

在表达式中:...

以及TS.singletonTM.lookupTS.memberTS.findMin的类似内容。

我似乎没有得到实际问题,也不知道如何向[inline]表达式添加类型声明(我已经看了几次,但没有得到语法)。你能帮帮我吗?

1 个答案:

答案 0 :(得分:1)

我无法重现这个问题。

如果没有trie的签名,我会 - 不出所料 - 一个模糊的类型变量错误(好吧,两个),因为问题中陈述的原因,以及可能的原因(这真的是原因,它是单态限制),两个可能的修复(禁用单态限制使其编译,但给出一个明确的类型签名是更好的修复)。对于过度兴趣的灵魂,这个错误信息附在下面(来自7.6.1)。

使用类型签名,它可以干净地编译。

鉴于此,我无法确定地诊断出问题,但与您所获得的错误信息一起经历可能会导致问题。

您收到一条非常具体的消息,表明所需的实例不在范围内:

No instance for (Data.ListTrie.Base.Map.Map Map.Map Char) arising from a use of TrieM.fromListWith'

Possible fix: add an instance declaration for (Data.ListTrie.Base.Map.Map Map.Map Char)

另一方面,list-tries包显式提供了这样的实例。

这种情况的典型原因是,有两个不同的类或两个不同的类型来自同一个包的不同版本。

在这种情况下,您可能针对list-tries的一个版本构建了containers,后来安装了containers的不同版本,而import qualified Data.Map as Map导入了Map.Map 1}}从较新的软件包版本中键入,而list-tries中的实例用于旧版本。

检查是否安装了多个containers版本的

ghc-pkg list containers

检查containers取决于list-tries的哪个版本

ghc-pkg describe list-tries

在输出的depends字段中,会出现类似

的内容
containers-0.5.0.0-e49be7a240765a4edc5c09f677ec6a81

列出了containerslist-tries的包版本和ABI哈希值。

如果版本与您安装的containers的最新版本不对应,则会出现上述情况,除非在调用GHC时明确指定要使用的containers版本,或者直接使用-package标记,或通过.cabal文件间接标记。

如果是这种情况,您可以

  • 明确指定每次使用containers
  • 时要使用的list-tries版本
  • 取消注册containers的新版本(可能会破坏其他软件包)
  • 针对较新版本的list-tries
  • 重建containers

TrieTest.hs:12:8:
    No instance for (Data.ListTrie.Base.Map.Map map0 Char)
      arising from a use of TM.fromListWith'
    The type variable `map0' is ambiguous
    Possible cause: the monomorphism restriction applied to the following:
      trie :: TM.TrieMap map0 Char (TS.TrieSet map1 Char)
        (bound at TrieTest.hs:12:1)
    Probable fix: give these definition(s) an explicit type signature
                  or use -XNoMonomorphismRestriction
    Note: there are several potential instances:
      instance Eq k =>
               Data.ListTrie.Base.Map.Map Data.ListTrie.Base.Map.AList k
        -- Defined in `Data.ListTrie.Base.Map'
      instance Ord k => Data.ListTrie.Base.Map.Map Map.Map k
        -- Defined in `Data.ListTrie.Base.Map'
      instance Enum k =>
               Data.ListTrie.Base.Map.Map Data.ListTrie.Base.Map.WrappedIntMap k
        -- Defined in `Data.ListTrie.Base.Map'
    Possible fix:
      add an instance declaration for
      (Data.ListTrie.Base.Map.Map map0 Char)
    In the expression: TM.fromListWith' (flip TS.union)
    In the expression:
      TM.fromListWith' (flip TS.union)
      $ map (\ v -> (sort v, TS.singleton v)) vocabs
    In an equation for `trie':
        trie
          = TM.fromListWith' (flip TS.union)
            $ map (\ v -> (sort v, TS.singleton v)) vocabs

TrieTest.hs:12:31:
    No instance for (Data.ListTrie.Base.Map.Map map1 Char)
      arising from a use of `TS.union'
    The type variable `map1' is ambiguous
    Possible cause: the monomorphism restriction applied to the following:
      trie :: TM.TrieMap map0 Char (TS.TrieSet map1 Char)
        (bound at TrieTest.hs:12:1)
    Probable fix: give these definition(s) an explicit type signature
                  or use -XNoMonomorphismRestriction
    Note: there are several potential instances:
      instance Eq k =>
               Data.ListTrie.Base.Map.Map Data.ListTrie.Base.Map.AList k
        -- Defined in `Data.ListTrie.Base.Map'
      instance Ord k => Data.ListTrie.Base.Map.Map Map.Map k
        -- Defined in `Data.ListTrie.Base.Map'
      instance Enum k =>
               Data.ListTrie.Base.Map.Map Data.ListTrie.Base.Map.WrappedIntMap k
        -- Defined in `Data.ListTrie.Base.Map'
    Possible fix:
      add an instance declaration for
      (Data.ListTrie.Base.Map.Map map1 Char)
    In the first argument of `flip', namely `TS.union'
    In the first argument of TM.fromListWith', namely `(flip TS.union)'
    In the expression: TM.fromListWith' (flip TS.union)