2016-02-29 86 views
0

我刚开始学习Haskell,现在陷入了处理IO操作的困境。在Haskell处理IO操作时遇到困难

这是代码。

parseDnsMessage :: BG.BitGet DnsMessage 

recQuery :: BS.ByteString -> String -> IO BS.ByteString 

resolveName :: [Word8] -> [Word8] -> BS.ByteString -> String 
resolveName qname name bstr = do 
    let newbstr = BSL.toStrict $ replace (BS.pack qname) (BS.pack name) bstr 
    retbstr <- recQuery newbstr (head rootServers4) 
    let msg = BG.runBitGet retbstr parseDnsMessage 
    case msg of 
    Right m -> (intercalate "." $ map show (rdata $ head $ answer $ m)) 

---错误消息---

Couldn't match expected type ‘[BSI.ByteString]’ 
      with actual type ‘IO BSI.ByteString’ 
In a stmt of a 'do' block: 
    retbstr <- recQuery newbstr (head rootServers4) 
In the expression: 
    do { let newbstr 
      = BSL.toStrict $ replace (BS.pack qname) (BS.pack name) bstr; 
     retbstr <- recQuery newbstr (head rootServers4); 
     let msg = BG.runBitGet retbstr parseDnsMessage; 
     case msg of { 
     Right m 
      -> (intercalate "." $ map show (rdata $ head $ answer $ m)) } } 

我只是想找回从recQueryIO actionBS.ByteString

我该如何解决这个问题?

+1

问题是你的'resolveName'应该返回'IO String',而不是'String'。这是因为它在'IO' monad中运行,即你正在链接'IO'动作,所以它必须返回'IO'。 –

+2

可能的重复:[将IO字符串转换为“其他类型”](http://stackoverflow.com/q/15641584/1523776) –

+2

哦,这很有道理!非常感谢你。 – Sho

回答

1

问题是您的resolveName应该返回IO String而不是String。这是因为它在IO monad中运行,即您正在链接IO动作,所以它必须返回IO