10

我正在尝试在 haskell 中使用 Ubigraph,但我相信我的问题更普遍。我正在尝试编译:

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

我可以看到 op 的类型是如何被暗示为与 putStrLn 的返回类型不同的东西,但我不确定如何重新设计此代码以正确编译。我可以简单地更改 op 函数的返回类型吗?

谢谢

4

1 回答 1

12

你的要求被putStrLn埋葬op在单IO子里。您需要将其提升到Ubigraphmonad 中,使用

 liftIO $ putStrLn "foo"

此类提升函数可帮助您访问堆栈中较低的一元函数。在这种情况下,Ubigraph是由 IO monad 组成的 Reader monad,IO monad 在底部。所以必须解除IO中的东西。

liftIO来自MonadIO类,在变形金刚包中。

于 2011-04-27T15:41:25.427 回答