Haskell Wreq - не удалось сопоставить ожидаемый тип '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
. Есть идеи, что здесь может происходить?
2 ответа
Ясно (компилятору, если не вашему собрату), что
("num" := (31337 :: Int)) :: FormParam
. Что компилятору непонятно (и что вам нужно помочь ему решить), так это тип
[x]
однажды
x
известен как
FormParam
.
В
Item
"type" на самом деле является семейством типов, происходящим от класс; и
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]
вместо этого имеет тип
(GHC.Exts.IsList l, GHC.Exts.Item l ~ Bool) => l
. После объединения
print [True]
в конечном итоге в основном имеет тип
(Show a, GHC.Exts.IsList a, GHC.Exts.Item a ~ Bool) => IO ()
. Обратите внимание, что переменная типа нигде справа от
=>
, что делает этот тип неоднозначным. Чтобы сделать двусмысленность еще более конкретной, обратите внимание, что помимо
[Bool]
, тип
NonEmpty Bool
также будет работать на
a
там. Компилятор не знает, какой из них вы хотите, и не хочет угадывать, поэтому выдает эту ошибку. Чтобы решить проблему, добавьте аннотацию типа, например:
main = print ([True] :: [Bool])
Для реальной проблемы в вашем вопросе единственное отличие состоит в том, что у вас есть
Postable
typeclass вместо
Show
, а
FormParam
тип вместо
Bool
. Вы можете решить свою проблему, заменив строку с ошибкой на
res <- post "http://httpbin.org/post" (["num" := (31337 :: Int)] :: [FormParam])
.