2011-04-27 67 views
10

我想與哈斯克爾Ubigraph,但我相信我的問題是更通用的。我試圖編譯:在哈斯克爾混合Monads

import Graphics.Ubigraph 
import Control.Monad 
import System.Posix.Unistd 

main = do 
    h <- initHubigraph "http://127.0.0.1:20738/RPC2" 
    runHubigraph op h 

op = do 
    clear 
    vs <- mapM (const newVertex) [0..200] 
    mapM_ (setVAttr (VShape Sphere)) vs 
    putStrLn "something" 
    let bind i = zipWithM (\a b -> newEdge (a,b)) vs (drop i vs ++ take i vs) 
    mapM_ bind [1..15] 
    mapM_ (removeVertex) vs 
    return() 

和我得到

Couldn't match expected type `Control.Monad.Trans.Reader.ReaderT 
           Ubigraph IO a0' 
      with actual type `IO()' 
In the return type of a call of `putStrLn' 
In a stmt of a 'do' expression: putStrLn "something" 
In the expression: 
    do { clear; 
     vs <- mapM (const newVertex) [0 .. 200]; 
     mapM_ (setVAttr (VShape Sphere)) vs; 
     putStrLn "something"; 
     .... } 

我可以看到如何運算的類型被隱含的東西從putStrLn的返回類型不同,但我不知道如何重新編譯這段代碼才能正確編譯。我可以簡單地改變op函數的返回類型嗎?

感謝

回答

12

您對putStrLn呼叫op埋在是在IO單子。你需要將它提升到了Ubigraph單子,使用

liftIO $ putStrLn "foo" 

這樣的升降功能,幫助您獲得一元函數較低的堆棧。在這種情況下,Ubigraph是由IO monad組成的Reader monad,IO monad位於底部。所以IO中的東西必須被解除。

liftIO來自MonadIO類,in the transformers package

+0

真棒,這很好。感謝您的快速回復 – 2011-04-27 15:53:09