2014-06-29 70 views
1

我有這樣的功能:無法找出一個函數的類型是什麼

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 

加上一些其他的但失敗。它是什麼?

回答

5

您到目前爲止嘗試失蹤的主要原因是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) 

要進入就如何得出正確的類型更多的細節,我們需要的類型simpleHttpeitherDecode仔細看:

eitherDecode :: FromJSON a => ByteString -> Either String a 
simpleHttp :: MonadIO m => String -> m ByteString 

他們也正在(<$>)Control.Applicative組合:

(<$>) :: Functor f => (a -> b) -> f a -> f b 

全部放在一起給出上述類型 - 的f(<$>)msimpleHttp必須是相同的,和輸入類型是被送入simpleHttpString,結果類型是eitherDecode的結果類型,解除由(<$>)操作轉換成m

你也可以讓GHC告訴你答案。或者用ghci加載你的模塊,並使用:t getJSON,或者省略類型簽名,用-Wall進行編譯,並查看關於getJSON的缺失類型簽名的警告。

5

請注意,您不必在Haskell中爲您的函數顯式聲明類型。編譯器會爲你推導出它們。實際上,您可以在ghci中使用:type命令(或簡稱爲:t)讓編譯器在加載源文件後告訴您函數的類型。

+0

當然,我不必。但是在使用它之前先聲明一個函數的類型是個好習慣。 –

+0

@Grienders是的,但「首先寫入沒有類型簽名的函數,然後問編譯器它的類型是什麼,然後添加簽名」是一個完美的方法。 –

相關問題