Haskell Wreq - 无法匹配预期类型“GHC.Exts.Item a0”
Haskell Wreq - Couldn't match expected type ‘GHC.Exts.Item a0’
我在 运行 以下代码时遇到类型错误:
runPost :: IO String
runPost = do
res <- post "http://httpbin.org/post" ["num" := (31337 :: Int)]
return $ show res
错误如下:
• Couldn't match expected type ‘GHC.Exts.Item a0’
with actual type ‘FormParam’
The type variable ‘a0’ is ambiguous
• In the expression: "num" := (31337 :: Int)
In the second argument of ‘post’, namely
‘["num" := (31337 :: Int)]’
In a stmt of a 'do' block:
res <- post "http://httpbin.org/post" ["num" := (31337 :: Int)]
当我在 ghci 中检查 :=
的类型时,我看到什么似乎是正确的类型:
*Main Network.Wreq> :t (:=)
(:=)
:: FormValue v =>
Data.ByteString.Internal.ByteString -> v -> FormParam
我想知道的是,当我 运行 编译器时,为什么 GHC.Exts.Item
显示为预期类型。我只从 Network.Wreq
导入了我正在使用的函数。知道这里会发生什么吗?
("num" := (31337 :: Int)) :: FormParam
很清楚(对编译器而言,如果不是对你的人类同胞而言)。一旦 x
被认为是 FormParam
.
,编译器不清楚的(以及您需要帮助它决定的)是 [x]
的类型
Item
“类型”实际上是一个类型家族,来自IsList
class;并且 IsList
连接来自 OverloadedLists
扩展打开。
这是一个导致基本相同错误的最小程序,它应该更清楚发生了什么:
{-# LANGUAGE OverloadedLists #-}
main :: IO ()
main = print [True]
• Couldn't match expected type ‘GHC.Exts.Item a0’
with actual type ‘Bool’
The type variable ‘a0’ is ambiguous
• In the expression: True
In the first argument of ‘print’, namely ‘[True]’
In the expression: print [True]
|
4 | main = print [True]
| ^^^^
print
函数的类型为 Show a => a -> IO ()
。如果未启用 OverloadedLists
扩展,那么表达式 [True]
的类型将是 [Bool]
,一切都会好起来的。但是启用 OverloadedLists
扩展后,表达式 [True]
的类型改为 (GHC.Exts.IsList l, GHC.Exts.Item l ~ Bool) => l
。统一后,print [True]
基本上变成了 (Show a, GHC.Exts.IsList a, GHC.Exts.Item a ~ Bool) => IO ()
类型。请注意,类型变量 a
没有出现在 =>
右侧的任何位置,这使得它成为一个不明确的类型。为了使歧义更加具体,请注意,除了 [Bool]
之外,类型 NonEmpty Bool
也适用于 a
。编译器不知道你想要哪一个,也不想猜测,所以它给了你那个错误。为了解决这个问题,添加一个类型注释,像这样:main = print ([True] :: [Bool])
对于您问题中的实际问题,唯一的区别是您使用 Postable
类型类而不是 Show
,并且使用 FormParam
类型而不是 Bool
.您可以通过将错误行替换为 res <- post "http://httpbin.org/post" (["num" := (31337 :: Int)] :: [FormParam])
.
来解决您的问题
我在 运行 以下代码时遇到类型错误:
runPost :: IO String
runPost = do
res <- post "http://httpbin.org/post" ["num" := (31337 :: Int)]
return $ show res
错误如下:
• Couldn't match expected type ‘GHC.Exts.Item a0’
with actual type ‘FormParam’
The type variable ‘a0’ is ambiguous
• In the expression: "num" := (31337 :: Int)
In the second argument of ‘post’, namely
‘["num" := (31337 :: Int)]’
In a stmt of a 'do' block:
res <- post "http://httpbin.org/post" ["num" := (31337 :: Int)]
当我在 ghci 中检查 :=
的类型时,我看到什么似乎是正确的类型:
*Main Network.Wreq> :t (:=)
(:=)
:: FormValue v =>
Data.ByteString.Internal.ByteString -> v -> FormParam
我想知道的是,当我 运行 编译器时,为什么 GHC.Exts.Item
显示为预期类型。我只从 Network.Wreq
导入了我正在使用的函数。知道这里会发生什么吗?
("num" := (31337 :: Int)) :: FormParam
很清楚(对编译器而言,如果不是对你的人类同胞而言)。一旦 x
被认为是 FormParam
.
[x]
的类型
Item
“类型”实际上是一个类型家族,来自IsList
class;并且 IsList
连接来自 OverloadedLists
扩展打开。
这是一个导致基本相同错误的最小程序,它应该更清楚发生了什么:
{-# LANGUAGE OverloadedLists #-}
main :: IO ()
main = print [True]
• Couldn't match expected type ‘GHC.Exts.Item a0’
with actual type ‘Bool’
The type variable ‘a0’ is ambiguous
• In the expression: True
In the first argument of ‘print’, namely ‘[True]’
In the expression: print [True]
|
4 | main = print [True]
| ^^^^
print
函数的类型为 Show a => a -> IO ()
。如果未启用 OverloadedLists
扩展,那么表达式 [True]
的类型将是 [Bool]
,一切都会好起来的。但是启用 OverloadedLists
扩展后,表达式 [True]
的类型改为 (GHC.Exts.IsList l, GHC.Exts.Item l ~ Bool) => l
。统一后,print [True]
基本上变成了 (Show a, GHC.Exts.IsList a, GHC.Exts.Item a ~ Bool) => IO ()
类型。请注意,类型变量 a
没有出现在 =>
右侧的任何位置,这使得它成为一个不明确的类型。为了使歧义更加具体,请注意,除了 [Bool]
之外,类型 NonEmpty Bool
也适用于 a
。编译器不知道你想要哪一个,也不想猜测,所以它给了你那个错误。为了解决这个问题,添加一个类型注释,像这样:main = print ([True] :: [Bool])
对于您问题中的实际问题,唯一的区别是您使用 Postable
类型类而不是 Show
,并且使用 FormParam
类型而不是 Bool
.您可以通过将错误行替换为 res <- post "http://httpbin.org/post" (["num" := (31337 :: Int)] :: [FormParam])
.