使用readProcess

时间:2016-05-23 18:03:25

标签: haskell xmonad

我试图在没有真正理解的情况下配置XMonad Haskell语法。

我在xmonad上运行gnome会话。我想按mod-p来 切换gnome-panel:

  • 如果gnome面板没有运行,我想启动它。
  • 如果侏儒 面板已经在运行我想杀了它

我认为这样做会:

startgpanel :: X ()
startgpanel = do
  gp <- readProcess "pidof" ["gnome-panel"] ""
     if (length gp)
     then spawn "killall gnome-panel"
     else spawn "gnome-panel"

  ...
 ((myModMask, xK_g), startgpanel)
  ...

但是我收到了一个错误:

xmonad.hs:169:12:
    Couldn't match expected type âX (t0 a0)â
                with actual type âIO Stringâ
    In a stmt of a 'do' block:
      gp <- readProcess "pidof" ["gnome-panel"] ""
    In the expression:
      do { gp <- readProcess "pidof" ["gnome-panel"] "";
           if (length gp) then
               spawn "killall gnome-panel"
           else
               spawn "gnome-panel" }

我真的不了解Monad概念,我只想要 做一些IO,但看起来很复杂......

3 个答案:

答案 0 :(得分:1)

您需要在liftIO中包装IO操作以在X monad中运行它。 另外,您不能仅将length的结果用作Bool作为if语句,因为它返回Int

startgpanel :: X ()
startgpanel = do
  gp <- liftIO $ readProcess "pidof" ["gnome-panel"] ""
  if (length gp > 0)
    then spawn "killall gnome-panel"
    else spawn "gnome-panel"

答案 1 :(得分:1)

正如其他人所提到的,您需要使用liftIO

另请参阅对此SO问题的讨论:

How do I use the output of readProcess in an xmonad keybinding?

而不是readProcess您可能需要使用readProcessWithInput

答案 2 :(得分:-1)

由于xmonad对进程的所有肮脏,我建议你将整个一堆逻辑移到shell中;将键绑定到此操作:

spawn "pidof gnome-panel && killall gnome-panel || gnome-panel"

看看,没有do