我正在尝试使用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音量?
答案 0 :(得分: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感兴趣。