Haskell 无法从上下文推断(简单)类型类
我在一个非常简单的例子中遇到了一个错误,我无法找出错误所在。我所做的与Haskell 无法从上下文推断(简单)类型类,haskell,Haskell,我在一个非常简单的例子中遇到了一个错误,我无法找出错误所在。我所做的与Monoid中的mempty非常相似,这里有一个简单的版本(我包括我的量化类型,以防与问题有关): 我得到的错误是: Could not deduce (EsMappable t0) arising from a use of ‘fields’ from the context (EsMappable a) bound by the type signature for toMapping ::
Monoid
中的mempty
非常相似,这里有一个简单的版本(我包括我的量化类型,以防与问题有关):
我得到的错误是:
Could not deduce (EsMappable t0) arising from a use of ‘fields’
from the context (EsMappable a)
bound by the type signature for
toMapping :: EsMappable a => a -> String
at search2.hs:11:14-42
The type variable ‘t0’ is ambiguous
In the second argument of ‘go’, namely ‘fields’
In the expression: go "" fields
In an equation for ‘toMapping’:
toMapping a
= go "" fields
where
go str [] = str
go str (ReferenceField name _ : xs) = go (name ++ str) xs
go str (Field name : xs) = go (name ++ str) xs
注意:如果我将EsMapapble
类更改为:fields::a->[Field a]
,然后在映射中更改go”“(fields a)
,它会起作用
我的问题:为什么我会出现这个错误?这与mempty
不一样吗?是什么阻止GHC正确解析字段
谢谢大家! 问题在于编译器无法将字段的使用与参数a
链接起来。对于任何a
,您的go
函数都可以接受[字段a]
,因此您需要以某种方式明确地将其约束为与参数类型中的a
相同
使用ScopedTypeVariables
可以很好地实现这一点:
toMapping :: forall a. (EsMappable a) => a -> String
toMapping _ = go "" (fields :: [Field a])
您需要为所有a
添加额外的,以显式地将a
类型变量范围化。为了向后兼容,这是对ScopedTypeVariables
的限制
如果将a
参数与go
中的字段a
值一起使用,这也不会是一个问题。作为一个人为的例子,以下类型检查没有明确的签名:
go str (ReferenceField name f : xs) = go (name ++ str) xs `const` f a
这将强制f
采用类型为a
的参数,这将整个列表约束为特定的a
。因此,如果您真的想要,您实际上可以使用这个技巧来避免ScopedTypeVariables
扩展!不过,我不建议这样做:这个扩展几乎是无害的,并且使代码更加清晰。这个例子只是为了说明我的观点。谢谢你的快速回答。我现在明白了其中的微妙之处。此外,看到您使用const
约束a
的示例非常有帮助,也是一个很好的例子,尽管有点老套,但说明了懒惰是有用的!
go str (ReferenceField name f : xs) = go (name ++ str) xs `const` f a