2011-04-27 12 views
10

Estoy tratando de trabajar con Ubigraph en haskell, pero creo que mi problema es más genérico. Estoy intentando compilar:Mezcla de mónadas en Haskell

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() 

y estoy consiguiendo

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"; 
     .... } 

puedo ver cómo el tipo de OP se implicó como algo diferente del tipo de retorno de putStrLn, pero no estoy seguro de cómo rediseñaré este código para compilarlo correctamente. ¿Puedo simplemente cambiar el tipo de devolución de la función op?

Gracias

Respuesta

12

Su llamada a putStrLn enterrada en op se encuentra en la IO mónada. Usted tendrá que elevar ésta en la Ubigraph mónada, utilizando

liftIO $ putStrLn "foo" 

Tales funciones de elevación ayudan a acceder a las funciones monádicos abajo en la pila. En este caso, Ubigraph es una mónada Reader compuesta con la mónada IO, y la mónada IO está en la parte inferior. Entonces las cosas en IO deben ser levantadas.

liftIO pertenece a la clase MonadIO, in the transformers package.

+0

increíble, que funcionó muy bien. Gracias por la rápida respuesta –