我有这个功能:
import Data.Aeson
import Network.HTTP.Conduit
getJSON url = eitherDecode <$> simpleHttp url
被称为:
maybeJson <- getJSON "https://abc.com" :: IO (Either String Value)
但是,我无法弄清楚getJSON的类型是什么。我一直在尝试这些:
getJSON :: FromJSON a => String -> Either String a --1
getJSON :: String -> Either String Value --2
加上其他一些但失败了。它是什么?
答案 0 :(得分:4)
到目前为止,您尝试遗漏的主要内容是IO
类型。根据您当前的使用情况,一种正确的类型是
getJSON :: String -> IO (Either String Value)
您可以看到,IO
行必须提供maybeJSON
类型,以明确getJSON <something>
返回IO (Either String Value)
。
事实上,确切类型更为通用:
getJSON :: (FromJSON a, MonadIO m, Functor m) => String -> m (Either String a)
要详细了解如何推导出正确的类型,我们需要仔细查看simpleHttp
和eitherDecode
的类型:
eitherDecode :: FromJSON a => ByteString -> Either String a
simpleHttp :: MonadIO m => String -> m ByteString
他们还与Control.Applicative
的(<$>)
合并:
(<$>) :: Functor f => (a -> b) -> f a -> f b
将所有内容放在一起会得到上面的类型 - f
(<$>)
和m
simpleHttp
必须相同,输入类型为{{ 1}}被输入String
,结果类型是simpleHttp
的结果类型,被eitherDecode
操作提升为m
。
您也可以请GHC告诉您答案。在ghci中加载模块并使用(<$>)
,或省略类型签名,使用:t getJSON
进行编译,并查看有关-Wall
缺少类型签名的警告。
答案 1 :(得分:4)
请注意,您不必在Haskell中为函数显式声明类型。编译器会为您推断出它们。实际上,您可以在:type
中使用:t
命令(或简称ghci
)让编译器在加载源文件后告诉您函数的类型。