2013-02-26 57 views
0

我正在嘗試使用haskell-libmpd讀取XMonad中的MPD卷。雖然獨立代碼:如何使用XMonad顯示MPD卷

-- current darcs as of 2010-12-31 
{-# LANGUAGE 
    DeriveDataTypeable, 
    FlexibleContexts, 
    FlexibleInstances, 
    MultiParamTypeClasses, 
    NoMonomorphismRestriction, 
    PatternGuards, 
    ScopedTypeVariables, 
    TypeSynonymInstances, 
    UndecidableInstances, 
    OverloadedStrings 
    #-} 
{-# OPTIONS_GHC -W -fwarn-unused-imports -fno-warn-missing-signatures #-} 

import Control.Applicative 
import Control.Monad 
import Control.Monad.Instances() 
import Control.Monad.Writer 
import Control.Monad.Trans (liftIO) 
import Data.List 
import Data.Int 
import Data.Maybe 
import Data.Either 
import Data.Either.Utils 
import Data.Traversable(traverse) 
import qualified Data.Map as M 
import System.IO 
import System.Environment (getArgs) 
import System.Process 
import Prelude 
import Text.Regex.Posix 
import qualified Network.MPD as MPD 
import qualified Network.MPD.Commands.Extensions as MPD 
import Data.Array 
import System.Cmd 

int2str :: (Show a, Num a, Ord a) => a -> String 
int2str x = if x < 10 then '0':sx else sx where sx = show x 

parseMPD :: MPD.Response MPD.Status -> [[String]] 
parseMPD (Left e) = return $ show e:repeat "" 
parseMPD (Right st) = do 
    return [vol, "%"] 
    where 
      vol = int2str $ MPD.stVolume st 
--   song = MPD.withMPD MPD.currentSong 


main = do 
    x <- MPD.withMPD $ MPD.status 
    let a = unwords (foldr1 (++) (parseMPD x)) 
    rawSystem "notify-send" ["MPD Volume", a] 

編譯正確,在XMonad配置

int2str :: (Show a, Num a, Ord a) => a -> String 
int2str x = if x < 10 then '0':sx else sx where sx = show x 

parseMPD :: MPD.Response MPD.Status -> [[String]] 
parseMPD (Left e) = return $ show e:repeat "" 
parseMPD (Right st) = do 
    return [vol, "%"] 
    where 
      vol = int2str $ MPD.stVolume st 

volume :: MonadIO m => m() 
volume = do 
    x <- MPD.withMPD $ MPD.status 
    let a = unwords (foldr1 (++) (parseMPD x)) 
    safeSpawn "notify-send" ["MPD Volume", a] 

使用相同的代碼導致錯誤:

xmonad.hs:182:14: 
    Could not deduce (m ~ IO) 
    from the context (MonadIO m) 
     bound by the type signature for volume :: MonadIO m => m() 
     at xmonad.hs:180:11-26 
     `m' is a rigid type variable bound by 
      the type signature for volume :: MonadIO m => m() 
      at xmonad.hs:180:11 
    Expected type: m (MPD.Response MPD.Status) 
     Actual type: IO (MPD.Response MPD.Status) 
    In a stmt of a 'do' block: x <- MPD.withMPD $ MPD.status 
    In the expression: 
     do { x <- MPD.withMPD $ MPD.status; 
      let a = unwords (foldr1 (++) (parseMPD x)); 
      safeSpawn "notify-send" ["MPD Volume", a] } 
    In an equation for `volume': 
     volume 
      = do { x <- MPD.withMPD $ MPD.status; 
        let a = ...; 
        safeSpawn "notify-send" ["MPD Volume", ....] } 

我怎樣才能MPD量而不運行外部應用程序?

回答

1

答案:你在你的xmonad配置中沒有使用相同的代碼,你是騙子!您爲volume添加了綁定。不要擔心,雖然,它應該很容易解決:您可以將任何IO a行動統一到一個MonadIO m => m a行動liftIO

volume :: MonadIO m => m() 
volume = do 
    x <- liftIO . MPD.withMPD $ MPD.status 
    let a = unwords (foldr1 (++) (parseMPD x)) 
    safeSpawn "notify-send" ["MPD Volume", a] 

順便說一句,你以後可能會變得興趣XMonad.Prompt.MPD