XMonad中使用runProcessWithInput获取窗口名类型不匹配问题求助
问题:XMonad中
runProcessWithInput获取窗口名的类型不匹配错误 问题背景
尝试使用XMonad.Util.Run中的runProcessWithInput调用xdotool获取活动窗口名,然后在spawn中拼接字符串显示通知,但出现类型不匹配错误。
初始代码
focusedWindow = spawn ("notify-send \"Focused on " <> readWindowName ++ "\"") readWindowName :: String readWindowName = let wn = runProcessWithInput "xdotool" ["getactivewindow getwindowname"] "" in wn
报错信息
xmonad.hs:236:121: error: • Couldn't match type ‘[Char]’ with ‘Char’ Expected: String Actual: [String] • In the expression: wn In the expression: let wn = runProcessWithInput "xdotool" [...] "" in wn In an equation for ‘readWindowName’: readWindowName = let wn = runProcessWithInput "xdotool" ... "" in wn | 236 | readWindowName = let wn = runProcessWithInput "xdotool" ["getactivewindow getwindowname"] "" in wn | ^^
尝试的其他写法
写法1:do块尝试
readWindowName' :: String readWindowName' = do wn <- runProcessWithInput "xdotool" ["getactivewindow getwindowname"] "" return wn
写法2:用unlines处理
readWindowName'' :: String readWindowName'' = let wn = runProcessWithInput "xdotool" ["getactivewindow getwindowname"] "" wn' = unlines wn in wn'
写法2的报错
xmonad.hs:236:51: error: • No instance for (MonadIO []) arising from a use of ‘runProcessWithInput’ • In the expression: runProcessWithInput "xdotool" ["getactivewindow getwindowname"] "" In an equation for ‘wn’: wn = runProcessWithInput "xdotool" ["getactivewindow getwindowname"] "" In the expression: let wn = runProcessWithInput "xdotool" [...] "" wn' = unlines wn in wn' | 236 | readWindowName = let wn = runProcessWithInput "xdotool" ["getactivewindow getwindowname"] "" |
问题分析与解决方案
首先要明确两个核心问题:
- 参数传递错误:
xdotool的getactivewindow和getwindowname是两个独立命令,需要拆成列表的两个元素,而不是合并成一个字符串。 - 类型误解:
runProcessWithInput的返回值是IO String(IO操作的结果),并非纯String或[String],必须在IO上下文里获取和使用。
正确实现方式
直接在IO上下文里完成窗口名获取与通知调用:
focusedWindow :: IO () focusedWindow = do windowName <- runProcessWithInput "xdotool" ["getactivewindow", "getwindowname"] "" spawn $ "notify-send \"Focused on " <> windowName <> "\""
如果需要封装获取窗口名的逻辑,可以定义一个IO类型的函数:
readWindowName :: IO String readWindowName = runProcessWithInput "xdotool" ["getactivewindow", "getwindowname"] "" focusedWindow :: IO () focusedWindow = do wn <- readWindowName spawn $ "notify-send \"Focused on " <> wn <> "\""
错误原因解释
- 初始写法把
IO String当成了纯String,类型完全不匹配。 - do块写法给函数声明的类型是
String,但do块返回的是IO String,类型冲突。 unlines需要的参数是[String],但runProcessWithInput返回的是IO String,试图把IO操作当成字符串列表处理,导致MonadIO []的错误——[]并不是IO monad的实例。
内容的提问来源于stack exchange,提问作者Anapal
相关产品推荐
相关产品推荐

