0

我正在尝试使用 haskell-libmpd 读取 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 音量?

4

1 回答 1

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感兴趣。

于 2013-02-26T12:52:23.763 回答