Haskell 编译器推理和重载字符串

Haskell 编译器推理和重载字符串,haskell,ghc,Haskell,Ghc,我有以下代码 data RI a = Union (RI a) (RI a) | Kleene (RI a) | Concat (RI a) (RI a) | Const a | Empty | EmptySet deriving (Show) instance Monoid (RI a) where mempty = EmptySet mappend = Union instance IsString (RI Char) where fromString

我有以下代码

data RI a = Union (RI a) (RI a) | Kleene (RI a) |
            Concat (RI a) (RI a) | Const a | Empty | EmptySet deriving (Show)

instance Monoid (RI a) where
  mempty = EmptySet
  mappend = Union

instance IsString (RI Char) where
  fromString s = either (error "Incorrect Parse") (id) (getRE s)

instance IsString (RI Char -> RI Char) where
  fromString s = (\r -> mappend (fromString s) r)

runR :: RI Char -> String -> Bool 
runR r s = True

chain :: String -> Bool
chain = runR ("a" "b")
运行代码后,我得到:

re.hs:46:15:
    No instance for (IsString (a0 -> RI Char))
       arising from the literal ‘"a"’
    The type variable ‘a0’ is ambiguous
    Note: there is a potential instance available:
      instance IsString (RI Char -> RI Char) -- Defined at re.hs:39:10
    In the expression: "a"
    In the first argument of ‘runR’, namely ‘("a" "b")’
    In the expression: runR ("a" "b")

re.hs:46:19:
    No instance for (IsString a0) arising from the literal ‘"b"’
    The type variable ‘a0’ is ambiguous
    Note: there are several potential instances:
      instance IsString (RI Char -> RI Char) -- Defined at re.hs:39:10
      instance IsString (RI Char) -- Defined at re.hs:36:10
      instance IsString [Char] -- Defined in ‘Data.String’
      ...plus two others
    In the first argument of ‘"a"’, namely ‘"b"’
    In the first argument of ‘runR’, namely ‘("a" "b")’
    In the expression: runR ("a" "b")
Failed, modules loaded: none.
向链添加注释可以解决问题,但效果很差

chain = runR ("a" ("b" :: RI Char))

问题是,为什么编译器不能自己解决这个问题?
runR
的第一个参数的类型为
RI Char
,因此我们必须以某种方式将
“a”“b”
计算为该类型。根据我定义的实例,唯一的方法是对
“a”
使用
RI Char->RI Char
实例,对“b”使用
RI Char
实例。不幸的是,编译器没有这样做

同样的原因
(读“a”)(读“b”)
也不起作用。您需要某种方法来确定要选择的类实例。但是
fromString
的类型是
isstringa=>String->a
;类参数只在输出中提到,而不是在输入中提到,因此输入无法选择实例。仅仅因为只有一组实例会在作用域中生成有效的程序,并不意味着只有一组实例会存在。最简单的解决方法是为
RI Char->RI Char
创建一个新类型,假设您有
实例IsString(String->RI Char),其中…
。那么,
“a”“b”
就会模棱两可。正如我朋友指出的,谢谢你的评论。。“为什么不直接为所有内容编写IsString实例,并将程序编写为字符串序列呢?”。上面的代码已经重写,以避免这种滥用。