Haskell 尽管有明确的 Bool 类型注释,正则表达式上下文不明确类型在 ghci 中成功
Haskell regex context ambiguous type despite explicit Bool type annotation, succeeds in 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 中成功,但在编译时无法捕获相同的指令,我该如何解决?
歧义不在于 x =~ "csv$"
的类型是什么 - 这已经从您对 filter
的使用中确定了。问题是 "csv$"
文字本身。根据错误消息,您启用了 OverloadedStrings
语言扩展。这里的歧义在于弄清楚 "csv$"
需要是哪种类型的字符串。
您的解决方案是
- 关闭
OverloadedStrings
(如果您不需要此模块),或
- 向
"csv$"
添加类型注释,因此您有 \x -> x =~ ("csv$" :: String)
而不是 \x -> x =~ "csv$" :: Bool
如果这是一个经常出现的问题,您可能需要尝试使用 ExtendedDefaultRules
并在您的文件中包含一个 default
声明。
这在 GHCi 中成功的原因可能是因为您没有在那里启用 OverloadedStrings
(或者可能是由于 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 中成功,但在编译时无法捕获相同的指令,我该如何解决?
歧义不在于 x =~ "csv$"
的类型是什么 - 这已经从您对 filter
的使用中确定了。问题是 "csv$"
文字本身。根据错误消息,您启用了 OverloadedStrings
语言扩展。这里的歧义在于弄清楚 "csv$"
需要是哪种类型的字符串。
您的解决方案是
- 关闭
OverloadedStrings
(如果您不需要此模块),或 - 向
"csv$"
添加类型注释,因此您有\x -> x =~ ("csv$" :: String)
而不是\x -> x =~ "csv$" :: Bool
如果这是一个经常出现的问题,您可能需要尝试使用 ExtendedDefaultRules
并在您的文件中包含一个 default
声明。
这在 GHCi 中成功的原因可能是因为您没有在那里启用 OverloadedStrings
(或者可能是由于 GHCi 的不同默认规则)。