Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 无法推断两个受约束类型是相同的_Haskell - Fatal编程技术网

Haskell 无法推断两个受约束类型是相同的

Haskell 无法推断两个受约束类型是相同的,haskell,Haskell,我有几个类构成了更广泛层次结构的一部分,我正试图在DepTag上实现它们: class StanfordType a where text :: a -> Text class StanfordType a => Dep a where relation :: (StanfordType b) => a -> b data DepTag a b where DepTag :: (StanfordType a) => Text -> a ->

我有几个类构成了更广泛层次结构的一部分,我正试图在
DepTag
上实现它们:

class StanfordType a where
  text :: a -> Text

class StanfordType a => Dep a where
  relation :: (StanfordType b) => a -> b

data DepTag a b where
  DepTag :: (StanfordType a) => Text -> a -> DepTag Text a

instance StanfordType (DepTag a b) where 
  text (DepTag s _) = s

instance Dep (DepTag a b) where 
  relation (DepTag _ r) = r
当我试图编译此文件时,会抛出以下错误:

• Could not deduce: b ~ b1
  from the context: (a ~ Text, N.StanfordType b)
    bound by a pattern with constructor:
               DepTag :: forall b. N.StanfordType b => Text -> b -> DepTag Text b,
             in an equation for ‘relation’
    at src/NLP/Data.hs:17:45-54
  ‘b’ is a rigid type variable bound by
    the instance declaration at src/NLP/Data.hs:17:10
  ‘b1’ is a rigid type variable bound by
    the type signature for:
      relation :: forall b1. N.StanfordType b1 => DepTag a b -> b1
    at src/NLP/Data.hs:17:35
• In the expression: r
  In an equation for ‘relation’: relation (DepTag _ r) = r
  In the instance declaration for ‘N.Dep (DepTag a b)’
• Relevant bindings include
    r :: b (bound at src/NLP/Data.hs:17:54)
    relation :: DepTag a b -> b1 (bound at src/NLP/Data.hs:17:35)
我不明白为什么编译器看不到
关系中的
r
(Dep)和
关系的类型签名中的
b
是相同的。我错过了什么

我不明白为什么编译器看不到关系中的r(Dep)和关系的类型签名中的b是相同的

问题是它们不一样。这里的问题是,
关系::(Dep a,StanfordType b)=>a->b
必须能够返回每个有效的
b
。因此,虽然您对类型签名的理解是,您可以返回您(关系的编写者)想要的任何
b
,但实际上这意味着您必须返回我(关系的调用方)想要的任何
b
。我们可以这样明确地区别(第二种变体不是实际的Haskell语法,第一种不是标准的Haskell语法):

因此,如果生成一个类型
Foo
,这就是
StanfordType
的一个实例:

newtype Foo = Foo | Bar
instance StanfordType Foo where
   text = pack "FooBar"
现在,您可以使用GHCi验证,解析实际上必须能够返回类型为
Foo
的值:

 > :t resolution :: Dep a => a -> Foo
 resolution :: Dep a => a -> Foo :: Dep a => a -> Foo
当然,不可能使用
StanfordType
实例创建任何未知类型的值。特别是因为每个类型都可以有一个
StanfordType
实例

实际上,我们可以使用存在式来表示第二种类型:

data ExtStanfordType where
   EST :: StanfordType a => a -> ExtStanfordType

class StanfordType a => Dep a where
    relation :: a -> ExtStanfordType

instance Dep (DepTag a b) where
    relation = (DepTag _ r) = EST r
现在resolution可以返回任何封装在
ExtStanfordType
中的
StanfordType
。然后可以像这样使用
text

 textExt :: ExtStanfordType -> Text
 textExt (EST b) = text b
另见:

我不明白为什么编译器看不到关系中的r(Dep)和关系的类型签名中的b是相同的

问题是它们不一样。这里的问题是,
关系::(Dep a,StanfordType b)=>a->b
必须能够返回每个有效的
b
。因此,虽然您对类型签名的理解是,您可以返回您(关系的编写者)想要的任何
b
,但实际上这意味着您必须返回我(关系的调用方)想要的任何
b
。我们可以这样明确地区别(第二种变体不是实际的Haskell语法,第一种不是标准的Haskell语法):

因此,如果生成一个类型
Foo
,这就是
StanfordType
的一个实例:

newtype Foo = Foo | Bar
instance StanfordType Foo where
   text = pack "FooBar"
现在,您可以使用GHCi验证,解析实际上必须能够返回类型为
Foo
的值:

 > :t resolution :: Dep a => a -> Foo
 resolution :: Dep a => a -> Foo :: Dep a => a -> Foo
当然,不可能使用
StanfordType
实例创建任何未知类型的值。特别是因为每个类型都可以有一个
StanfordType
实例

实际上,我们可以使用存在式来表示第二种类型:

data ExtStanfordType where
   EST :: StanfordType a => a -> ExtStanfordType

class StanfordType a => Dep a where
    relation :: a -> ExtStanfordType

instance Dep (DepTag a b) where
    relation = (DepTag _ r) = EST r
现在resolution可以返回任何封装在
ExtStanfordType
中的
StanfordType
。然后可以像这样使用
text

 textExt :: ExtStanfordType -> Text
 textExt (EST b) = text b

另请参见:

我不知道如何实现
关系
。StanfordType基本上只是
Show
,但是带有
Text
,因此
关系几乎是
(Dep a,Show b)=>a->b
。您想如何快速生成任何
showt=>t
值?这似乎几乎是不可能的。就像实现一个(total)函数
a->b
。编译器无法计算出它们是相同的,因为它们不是。
Dep
定义中的类型变量与
DepTag
@jpath定义中的
b
不同,我肯定遗漏了一些东西,因为我不明白它们为什么不一样
DepTag
有两个参数,我认为第二个参数被限制为
StanfordType
的成员。函数
关系
还返回一个值,该值被限制为
StanfordType
的成员。我遗漏了什么?
b
可以是斯坦福类型的任何成员。因此,如果我创建一个类型
Foo
,并使其成为
StandfordType
的成员。然后
relation
必须能够快速生成
Foo
s,因为
relation::Dep a=>a->Foo
relation
的有效实例化。你能给我一个有效的
Foo
值吗?谢谢你的帮助,不过我还是不太明白。如果我决定实现1000个
StanfordType
,我不明白它们是如何影响
关系的。只要
relation
能够返回
StanfordType
的1000个成员中的至少一个,不是吗?我不知道如何实现
relation
。StanfordType基本上只是
Show
,但是带有
Text
,因此
关系几乎是
(Dep a,Show b)=>a->b
。您想如何快速生成任何
showt=>t
值?这似乎几乎是不可能的。就像实现一个(total)函数
a->b
。编译器无法计算出它们是相同的,因为它们不是。
Dep
定义中的类型变量与
DepTag
@jpath定义中的
b
不同,我肯定遗漏了一些东西,因为我不明白它们为什么不一样
DepTag
有两个参数,我认为第二个参数被限制为
StanfordType
的成员。函数
关系
还返回一个值,该值被限制为
StanfordType
的成员。我遗漏了什么?
b
可以是斯坦福类型的任何成员。因此,如果我创建一个类型
Foo
,并使其成为
StandfordType
的成员。然后必须设置
关系