Haskell - 模棱两可的类型变量

Posted

技术标签:

【中文标题】Haskell - 模棱两可的类型变量【英文标题】:Haskell - Ambiguous type variable 【发布时间】:2015-04-13 23:42:35 【问题描述】:

我在几个模棱两可的类型变量错误问题中找不到我的问题的答案。

基本上我想将类型信息带到价值级别。此示例中的最后一行失败。

-# LANGUAGE MultiParamTypeClasses #-
-# LANGUAGE FunctionalDependencies #-
-# LANGUAGE FlexibleInstances #-
-# LANGUAGE UndecidableInstances #-
-# LANGUAGE TypeOperators #-

module Test where

data Typ = TInteger | TString deriving Show

data Empty = Empty
data a ## b = Cons a b

class Typical a b | a -> b where
    typical :: a -> b

instance Typical Empty [Typ] where
    typical _ = []

instance Typical Integer Typ where
    typical _ = TInteger

instance Typical String Typ where
    typical _ = TString

instance (Typical a Typ, Typical b [Typ]) => Typical (a ## b) [Typ] where
    typical _ = typical (undefined :: a) : typical (undefined :: b)

这是第一条错误信息:

Test.hs:27:17:
Could not deduce (Typical a0 Typ) arising from a use of `typical'
from the context (Typical a Typ, Typical b [Typ])
  bound by the instance declaration at Test.hs:26:10-67
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
  instance Typical String Typ -- Defined at Test.hs:23:10
  instance Typical Integer Typ -- Defined at Test.hs:20:10
Possible fix: add an instance declaration for (Typical a0 Typ)
In the first argument of `(:)', namely `typical (undefined :: a)'
In the expression:
  typical (undefined :: a) : typical (undefined :: b)
In an equation for `typical':
    typical _ = typical (undefined :: a) : typical (undefined :: b)

我只是不明白。

这里的a0 是什么?会不会是我最后一行中的a 与倒数第二行中的没有标识?

我应该把类型签名放在哪里?为什么?

请赐教!

【问题讨论】:

添加一个函数依赖声明一个类型是uniquely determined by another。我相信您需要删除 Typical a Typ 的一个实例,或者为组合实例的每个可能变体创建特定实例。 @Mokosha:函数依赖是a -> b,而不是b -> a,所以我认为不必删除实例。我想我没有听懂你最后一句话的第二部分。 【参考方案1】:

好的,我有一个解决方案,但我不知道这是否是最干净的解决方法。

添加-# LANGUAGE ScopedTypeVariables #- 使代码编译。这使得从错误消息中识别a0a 成为可能(对应于代码最后两行中的as)。

请发表评论!

【讨论】:

ScopedTypeVariables 是获得您想要的东西的正确方法。否则,局部类型注释中的变量都被隐式量化。独立地,如果你永远不需要typical 的第一个参数的实际值,最好使用代理:hackage.haskell.org/package/base-4.8.0.0/docs/… @kosmikus:谢谢。在遵循该参考之后,我的印象是Data.Reflection 做了我在这里尝试构建的内容。

以上是关于Haskell - 模棱两可的类型变量的主要内容,如果未能解决你的问题,请参考以下文章

在 Haskell 中编写 AI Solver 时的类型变量不明确

Haskell 模棱两可的出现——如何避免?

为什么Haskell说这是模棱两可的?

类型变量条件下的Haskell实例

Haskell概率单子的类型类问题

“类型变量不明确”在 Haskell Yesod 中使用 Persistent