You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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"] ""
    |              

问题分析与解决方案

首先要明确两个核心问题:

  1. 参数传递错误:xdotool的getactivewindow和getwindowname是两个独立命令,需要拆成列表的两个元素,而不是合并成一个字符串。
  2. 类型误解: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:20:09