我试图在没有真正理解的情况下配置XMonad Haskell语法。
我在xmonad上运行gnome会话。我想按mod-p来 切换gnome-panel:
我认为这样做会:
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,但看起来很复杂......
答案 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
!