Haskell正则表达式上下文模糊类型尽管有明确的Bool类型注释,但在ghci中成功

时间:2017-01-15 08:06:56

标签: haskell ghci

这适用于翻译会话

λ> import Text.Regex.Base
λ> import Text.Regex.Posix
λ> import Data.List (sort)
λ> import System.Directory

λ> ls <- getDirectoryContents "."
λ> let csvs = sort $ filter (\x -> x =~ "csv$" :: Bool) ls
λ> recent = last csvs

这很棒,并且完全符合我的需要。

但是,相同的代码无法在脚本中编译:

t10.hs:40:35-45: error: …
    • Ambiguous type variable ‘source0’ arising from a use of ‘=~’
      prevents the constraint ‘(RegexMaker
                                  Regex CompOption ExecOption source0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘source0’ should be.
      These potential instances exist:
        instance RegexMaker Regex CompOption ExecOption C.ByteString
          -- Defined in ‘Text.Regex.Posix.ByteString’
        instance RegexMaker Regex CompOption ExecOption LB.ByteString
          -- Defined in ‘Text.Regex.Posix.ByteString.Lazy’
    • In the expression: x =~ "csv$" :: Bool
      In the first argument of ‘filter’, namely
        ‘(\ x -> x =~ "csv$" :: Bool)’
      In the second argument of ‘($)’, namely
        ‘filter (\ x -> x =~ "csv$" :: Bool) ls’
t10.hs:40:40-45: error: …
    • Ambiguous type variable ‘source0’ arising from the literal ‘"csv$"’
      prevents the constraint ‘(Data.String.IsString
                                  source0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘source0’ should be.

我在最后有一个明确的:: Bool上下文来提供这些信息。为什么这会在ghci中取得成功,但在编译时未能捕获到相同的指令,我该如何解决?

1 个答案:

答案 0 :(得分:3)

歧义与x =~ "csv$"的类型无关 - 这已经由您使用filter确定。问题是"csv$"字面本身。根据错误消息,您启用了OverloadedStrings语言扩展。这里的歧义是弄清楚需要哪种类型的字符串"csv$"

您的解决方案是

  • 关闭OverloadedStrings(如果您不需要此模块)或
  • "csv$"添加类型注释,因此您拥有\x -> x =~ ("csv$" :: String)而不是\x -> x =~ "csv$" :: Bool

如果这是一个非常突出的问题,您可能想要使用ExtendedDefaultRules并在文件中添加default声明。

GHCi成功的原因可能是因为你没有启用OverloadedStrings(或者可能是由于GHCi的不同违约规则)。