这是一个示例函数:

import qualified Data.ByteString.Lazy as LAZ
import qualified Data.ByteString.Lazy.Char8 as CHA
import Network.Wreq

makeRequest :: IO (Network.Wreq.Response LAZ.ByteString)
makeRequest = do
   res <- get "http://www.example.com"
   let resBody = res ^. responseBody :: CHA.ByteString
   --Do stuff....
   return (res)

我正在努力理解这一行中 CHA.ByteString 的确切目的:
let resBody = res ^. responseBody :: CHA.ByteString

这是明确说明类型必须是 CHA.ByteString 吗?或者它扮演另一个角色?

最佳答案

是的,这只是明确说明类型必须是 CHA.ByteString 。这(本身)不会引起任何类型的转换,这只是对编译器(和/或读者)的一个提示,即 res 必须具有这种类型。

当一个值既由具有多态结果的函数产生,又仅由具有多态参数的函数使用时,就需要这些类型的局部注解。一个简单的例子:

f :: Int -> Int
f = fromEnum . toEnum

在这里, toEnum 将整数转换为任意可枚举类型——例如可以是 Char 。无论您选择哪种类型,fromEnum 都可以将其转换回来……麻烦的是,无法决定应将哪种类型用于中间结果!
No instance for (Enum a0) arising from a use of ‘fromEnum’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
  instance Integral a => Enum (GHC.Real.Ratio a)
    -- Defined in ‘GHC.Real’
  instance Enum Ordering -- Defined in ‘GHC.Enum’
  instance Enum Integer -- Defined in ‘GHC.Enum’
  ...plus 7 others
In the first argument of ‘(.)’, namely ‘fromEnum’
In the expression: fromEnum . toEnum
In an equation for ‘f’: f = fromEnum . toEnum

对于一些简单的数字类,Haskell 有默认值,例如fromIntegral . round 将自动使用 Integer 。但是像 ByteString 这样的类型没有默认值,所以对于像 responseBody 这样的多态结果函数,你要么需要将结果传递给一个只能接受 CHA.ByteString 的单态函数,要么你需要添加一个明确的注释,这应该是类型。

10-06 13:42
查看更多