運行以下代碼時遇到型別錯誤:
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在我運行編譯器時顯示為期望型別。我只匯入了我正在使用的函式 from Network.Wreq. 任何想法可能會發生什么?
uj5u.com熱心網友回復:
很明顯(對于編譯器,如果不是對于您的人類同胞),("num" := (31337 :: Int)) :: FormParam. 編譯器不清楚(以及您需要幫助它決定哪個)是[x]once的型別x被稱為FormParam.
在Item“型別”實際上是一個型別的家庭,從即將到來的IsList類; 并且IsList連接來自OverloadedLists打開擴展程式。
uj5u.com熱心網友回復:
這是一個導致基本相同錯誤的最小程式,它應該更清楚發生了什么:
{-# 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]將具有 type [Bool],一切都會好起來的。但是OverloadedLists啟用擴展后,運算式[True]改為具有 type (GHC.Exts.IsList l, GHC.Exts.Item l ~ Bool) => l。統一后,print [True]最終基本上有了 type (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]).
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316808.html
