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 に答える