user266003
user266003

Reputation:

Unable to figure out what the type of a function is

I have this function:

import Data.Aeson
import Network.HTTP.Conduit

getJSON url = eitherDecode <$> simpleHttp url

which is called as:

maybeJson <- getJSON "https://abc.com" :: IO (Either String Value)

However, I can't figure out what the type of getJSON is. I've been trying these:

getJSON :: FromJSON a => String ->  Either String a --1
getJSON :: String ->  Either String Value --2

plus some other ones but failed. What is it?

Upvotes: 1

Views: 66

Answers (2)

Ganesh Sittampalam
Ganesh Sittampalam

Reputation: 29100

The main thing you're missing in your attempts so far is the IO type. One correct type given your current usage is

getJSON :: String -> IO (Either String Value)

You can see that the IO type must be needed given your maybeJSON line - that makes it clear that getJSON <something> returns IO (Either String Value).

In fact the exact type is more general:

getJSON :: (FromJSON a, MonadIO m, Functor m) => String -> m (Either String a)

To go into more detail on how to derive the correct type, we need to look carefully at the types of simpleHttp and eitherDecode:

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

They're also being combined with (<$>) from Control.Applicative:

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

Putting it all together gives the type above - the f for (<$>) and the m for simpleHttp must be the same, and the input type is the String being fed into simpleHttp, and the result type is the result type of eitherDecode, lifted into m by the (<$>) operation.

You can also just ask GHC to tell you the answer. Either load your module up in ghci and use :t getJSON, or leave out the type signature, compile with -Wall and look at the warning about the missing type signature for getJSON.

Upvotes: 4

Code-Apprentice
Code-Apprentice

Reputation: 83517

Note that you don't have to explicitly declare a type for your functions in Haskell. The compiler will deduce them for you. In fact, you can use the :type command (or just :t for short) in ghci to let the compiler tell you the type of a function after you load the source file.

Upvotes: 4

Related Questions