参考haskell facebook example工作得很完美,但现在我无法弄清楚如何在一个单独的模块中拆分它,这样我就可以用它做一些有用的事情。另外我无法弄清楚我需要为fbEmail fbUrl添加什么类型,如果我需要在每个模块中放置OverloadedStrings?也许我的思维过程是错误的,简单的不可能将导入Network.HTTP.Conduit(withManager)与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
我收到以下错误
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;
.... }
代码更新6:见答案
答案 0 :(得分:2)
总结一下评论中发生的事情,问题基本上是三重的。您试图返回Maybe Text
而不是FacebookT ... (Maybe Text)
,由于缺少return
,缺少类型签名会导致单态限制,并最终忘记runFacebookT
在main
。
编辑:第四个问题是你给fbEmail
一个过多的多态类型,类型检查器抱怨类型变量a
实际上必须完全 { {1}}。编辑:在这里使用类型变量表明该函数可以应用于任何,但事实并非如此,因为(ByteString, ByteString)
想要一对列表getUserAccessTokenStep2
(而不仅仅是一个任意列表)。
编辑:第五个问题是由于要求ByteStrings
接管任何 monad太弱(withManager要求它是一堆更具体的东西,例如{ {1}})。正如你在错误中看到的那样,它只是一长串的事情,你可能最好只从FacebookT
删除类型签名并启用MonadIO
扩展名(只需将其添加到扩展名列表中)你有fbEmail
。
请注意,一般情况下你应该有明确的类型声明,但我不太熟悉管道包(我更多的是管道人员:P),我不知道是否有一些约束同义词技巧那里不那么冗长。
除非这些只是愚蠢的错别字,否则你可能想要阅读monad和monad变换器中的其中一个教程(或查看haskell wiki)。
此类问题也可能被认为对stackoverflow有点过于具体(请参阅常见问题解答),并且更适合于haskell IRC频道(一旦我们设法让它以您想要的方式运行,我就会标记它,但是将来我建议你在FreeNode上尝试IRC频道:))。