2016-05-23 1 views
1

Я пытаюсь настроить XMonad без фактического понимания синтаксиса Haskell .Конфигурация Haskell XMonad с использованием readProcess

Я запускаю сеанс гнома с xmonad сверху. Я хочу, чтобы нажать моды-р для тумблера гнома-панель:

  • если панель гнома не работает Я хочу, чтобы запустить его.
  • если панель гнома уже работает, я хочу, чтобы убить его

Я думал, что это будет сделать это:

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, я просто хочу, чтобы сделал несколько ввода-вывода, но кажется очень сложным ...

+0

похоже, что у вас был знак доллара в сообщении об ошибке, но не в коде, который вы отправили – hao

+0

Ошибка совпадает с $ или нет. Интересно, что означает «X (t0 a0)» ... –

+1

попробуйте добавить 'liftIO $ readProcess" pidof "...'. 'liftIO' способен преобразовывать вычисления' IO a' в вычисления 'X a' – hao

ответ

1

Как уже упоминалось, вам нужно использовать liftIO.

консультации также обсуждение этого вопроса: SO

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

Вместо readProcess вам может понадобиться использовать readProcessWithInput.

+0

Спасибо, я заработал с вашими намеками. –

1

Вам необходимо обернуть ваше действие IO в liftIO, чтобы запустить его в монаде X. Кроме того, вы не можете просто использовать результат length как Bool для если заявление, так как она возвращает Int:

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

Ошибка исчезла, спасибо, однако «pidof gnome-panel», похоже, не выполняется: xmonad-x86_64-linux: waitForProcess: не существует (нет дочерних процессов) waitForProcess: не существует (нет дочерних процессов) .. –

0

Из-за всей гадости xmonad делает с процессами, я бы предложил вам переместить всю чертову кучу логики в оболочку; привязать ключ к этой операции:

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

Смотри, мама, нет do!

+0

Умное решение, спасибо –