2014-10-18 21 views
4

GHC 7.6.3扩展OverloadedString不完全推断IsString。为什么?或者我错过了什么?

是一些代码无奈之举我试图编译

误差

No instance for (Data.String.IsString t3) 
arising from the literal `"meh"' 
The type variable `t3' is ambiguous 

我不明白。这是一个文字。什么是模糊的?为什么它不能推断这是一个字符串?

这是在呼叫未来像

foo bar "meh" 

其中foo不需要第二个参数是什么特别的(它必须满足一些typeclass,以及它为特定的连击是越来越。 )

我会注意到,我可以通过改变呼叫解决这个错误

foo bar ("meh" :: String) 

这显然是疯了。

- 编辑

也许它无关overloadedStrings

我可以 “复制” 这个错误只是

data B a where Foo :: a -> B A

然后在GHCI写简单

Foo "ok"

(显然失败,因为我没有获得Show,但为什么我也得到

No instance for (Data.String.IsString a0) arising from the literal `"ok"' The type variable `a0' is ambiguous ...

?这里发生了什么?这是什么意思?)

+0

由于没有足够的信息来推断该类型:'类型变量''t3'是不明确的'。你所描述的是一种典型的情况,即返回类型是多态的*和*参数类型也是多态的,所以GHC没有办法确定你实际需要什么类型。 – Rufflewind 2014-10-18 13:55:58

+0

您是否可以将问题重现为显示它的单一来源?因为你可以在这里看到一切工作https://www.fpcomplete.com/user/k_bx/untitled – 2014-10-18 14:07:57

回答

5

这是一个文字。什么是模糊的?为什么它不能推断这是一个字符串?

当您使用OverloadedStrings“meh”不是字面意思String。这是一个IsString a => a类型的字面多态值。它的类型不能被推断为String,因为它也可以作为一个懒惰ByteString,严格ByteStringText等。

foo不需要第二个参数是特别

什么

如果foo不要求第二个参数具体是什么,类型检查器如何知道foo的参数应该是String而不是Text等。

我会注意到我可以通过改变呼叫foo bar ("meh" :: String),这显然是疯了,修复这个错误。

现在您正在告诉类型检查器您想要哪种特定类型的"meh"

也许它无关overloadedStrings

这是正是OverloadedStrings。就个人而言,我建议不要使用OverloadedStrings,而只是使用Data.String.fromString,这正是因为您所看到的令人困惑的行为。

我可以“重现”这个错误只是...这里发生了什么?这是什么意思?

下面是一个具体的歧义示例。

{-# LANGUAGE OverloadedStrings, FlexibleInstances #-} 

import Data.Text 

class Foo a where 
    foo :: a -> String 

instance Foo String where 
    foo _ = "String" 

instance Foo Text where 
    foo _ = "Text" 

main :: IO() 
main = print (foo "meh") 

main应该打印什么?这取决于"meh"的类型。用户想要什么类型的"meh"?使用OverloadedStrings时,无法知道。

+0

那么为什么说“IsString”不能被推断?我不是要求推断“字符串”? – goingSpain 2014-10-18 23:20:15

+1

我同意你的例子,不清楚应该发生什么。 我感到困惑的是: 1)为什么不推断这个文献的IsString? 2)如果不是这样,如何通过一些扩展将文字看作“字符串”而不用明确的输入? – goingSpain 2014-10-18 23:24:30

+0

'String'和'IsString'是不同的东西。它不能推断出“IsString”推断,因为它不知道应该使用什么类型的字符串对象。您可以通过关闭OverloadedString来将字符串始终作为String来处理! – 2014-10-19 08:13:48