Reference haskell facebook example works perfect, but now I can’t figure out how to split it in a separate module so I can do something useful with it. Also I can’t figure out what type I need to put for fbEmail fbUrl and if I need to put OverloadedStrings in every module? Maybe my thinking process is wrong and its simple not possible to separate the import Network.HTTP.Conduit (withManager) from main?
login.hs
{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}
module Login (
fbUrl,
fbEmail
) where
import qualified Facebook as FB
import Network.HTTP.Conduit (withManager)
import Data.Text
import Data.ByteString.Internal (ByteString)
app :: FB.Credentials
app = FB.Credentials "localhost" "249348058430770" "..."
url :: FB.RedirectUrl
url = "http://localhost/fb"
perms :: [FB.Permission]
perms = ["user_about_me", "email"]
fbUrl = FB.getUserAccessTokenStep1 url perms
fbEmail c = withManager $ \manager -> FB.runFacebookT app manager $ do
t <- FB.getUserAccessTokenStep2 url [c]
u <- FB.getUser "me" [] (Just t)
return $ FB.userEmail u
main.hs
module Main (
main
) where
import Login
import System.IO
main :: IO ()
main = do
u <- fbUrl
print u
a <- readLn
e <- fbEmail a
print e
I get the following error
src/Main.hs:11:10:
Couldn't match expected type `IO t0'
with actual type `fb-0.9.6:Facebook.Monad.FacebookT
fb-0.9.6:Facebook.Monad.Auth m0 Data.Text.Internal.Text'
In a stmt of a 'do' block: u <- fbUrl
In the expression:
do { u <- fbUrl;
print u;
a <- readLn;
e <- fbEmail a;
.... }
In an equation for `main':
main
= do { u <- fbUrl;
print u;
a <- readLn;
.... }
CODE UPDATE 6: see answer
To summarise what was going on in the comments the issue was, essentially, threefold. You tried to return a
Maybe Textrather than aFacebookT ... (Maybe Text), due to missing areturn, the lack of type signatures made the monomorphism restriction kick inm and finally you forgot torunFacebookTinmain.EDIT: The fourth problem is that you’re giving
fbEmaila too polymorphic type, the type checker complains that the type variableaactually has to be exactly(ByteString, ByteString). EDIT: Using a type variable here states that the function could be applied to anything, which isn’t the case, asgetUserAccessTokenStep2wants a list of pairs ofByteStrings(rather than just an arbitrary list).EDIT: The fifth issue is due to the requirement that
FacebookTbe taken over any monad is too weak (withManager requires it to be a bunch of more specific things, such asMonadIO). As you can see in the error it’s rather a long list of things, and you might be better off just removing the type signature fromfbEmailand enable theNoMonomorphismRestrictionextension (just add it to the list of extensions where you haveOverloadedStrings.Note that generally you should have explicit type declarations, but I’m not too familiar with the conduits package (I’m more of a pipes person :P), and I don’t know if there is some constraint synonym trick there to make it less verbose.
Unless these were just silly typos you might want to read up on monads and monad transformers in one of the many tutorials floating around (or check the haskell wiki).
Also questions such as these might be considered a little too specific for stackoverflow (see the FAQ) and more appropriate to the haskell IRC channel (I’ll flag it once we’ve managed to got it running the way you want, but in future I suggest you try the IRC channel on FreeNode :)).