这是一个示例函数:
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
,或者您需要添加一个明确的注解,这应该是类型.