【发布时间】:2016-04-26 22:33:53
【问题描述】:
我正在尝试使用 taffybar 作为我的状态栏(使用 Dyre 框架,所以配置就是代码)。它有一个可以显示网络接口统计信息的小部件。在默认配置中,此小部件在编译时需要 String。我希望它为每个(非环回)接口动态创建一个小部件。
这是我目前所拥有的:
listNetworkDevices :: IO [String]
listNetworkDevices = fmap (map takeBaseName) $ getDirectoryContents "/sys/class/net/"
filterOutLoopback :: [String] -> [String]
filterOutLoopback = filter (\y -> not (elem y ["", ".", "lo"]))
netDevList :: IO [String]
netDevList = fmap filterOutLoopback listNetworkDevices
...
let nets = fmap (fmap (netMonitorNew 1)) netDevList
...
defaultTaffybar defaultTaffybarConfig {
...
endWidgets = [ tray, clock, mem, cpu] ++ nets ++ [ bat ]
}
此时我遇到以下编译器错误:
Couldn't match expected type ‘[IO gtk-0.14.2:Graphics.UI.Gtk.Types.Widget]’
with actual type ‘IO [IO gtk-0.14.2:Graphics.UI.Gtk.Types.Widget]’
总的来说,这个错误是有道理的,因为我从每个 String 中生成了一个 IO Widget。所以IO [String] 变成了IO [IO Widget]。
我不明白如何避免这样做。很明显,我一定是在某个时候出错了,但我看不出在哪里。我什至不知道如何用语言表达这个问题。我会很高兴任何指针!
相关资料:
- endWidgets 文档:https://hackage.haskell.org/package/taffybar-0.4.6/docs/System-Taffybar.html#v:endWidgets
- netMonitor 新文档:https://hackage.haskell.org/package/taffybar-0.4.6/docs/System-Taffybar-NetMonitor.html#v:netMonitorNew
- github来源:https://github.com/travitch/taffybar/tree/master/src/System/Taffybar
编辑:完整列表:
import System.Taffybar
import System.Taffybar.Systray
import System.Taffybar.Pager
import System.Taffybar.TaffyPager
import System.Taffybar.SimpleClock
import System.Taffybar.Battery
import System.Taffybar.NetMonitor
import System.Taffybar.Weather
import System.Taffybar.Widgets.PollingBar
import System.Taffybar.Widgets.PollingGraph
import System.Information.Memory
import System.Information.CPU
import System.Directory ( getDirectoryContents )
import System.FilePath ( takeBaseName )
import Control.Monad
memCallback = do
mi <- parseMeminfo
return [memoryUsedRatio mi]
cpuCallback = do
(userLoad, systemLoad, totalLoad) <- cpuLoad
return [totalLoad, systemLoad]
listNetworkDevices :: IO [String]
listNetworkDevices = fmap (map takeBaseName) $ getDirectoryContents "/sys/class/net/"
filterOutLoopback :: [String] -> [String]
filterOutLoopback = filter (\y -> not (elem y ["", ".", "lo"]))
netDevList :: IO [String]
netDevList = fmap filterOutLoopback listNetworkDevices
myPagerConfig = defaultPagerConfig {}
main = do
let memCfg = defaultGraphConfig { graphDataColors = [(1, 0, 0, 1)] }
cpuCfg = defaultGraphConfig { graphDataColors = [ (0, 1, 0, 1)
, (1, 0, 1, 0.5)
]
}
clock = textClockNew Nothing "<span fgcolor='orange'>%a %b %d %H:%M</span>" 1
pager = taffyPagerNew myPagerConfig
mem = pollingGraphNew memCfg 1 memCallback
cpu = pollingGraphNew cpuCfg 1 cpuCallback
bat = textBatteryNew "$percentage$% $time$" 1
tray = systrayNew
--nets = [ netMonitorNew 1 "wlp0s2" ]
nets = fmap (fmap (netMonitorNew 1)) netDevList
defaultTaffybar defaultTaffybarConfig { startWidgets = [ pager ]
, endWidgets = [ tray, clock, mem, cpu] ++ nets ++ [ bat ]
}
编辑:错误信息:
.config/taffybar/taffybar.hs:
Couldn't match expected type ‘[IO
gtk-0.14.2:Graphics.UI.Gtk.Types.Widget]’
with actual type ‘IO [IO gtk-0.14.2:Graphics.UI.Gtk.Types.Widget]’
In the first argument of ‘(++)’, namely ‘nets’
In the second argument of ‘(++)’, namely ‘nets ++ [bat]’
【问题讨论】:
-
能否添加完整的错误消息和引发错误的完整源代码函数。另外我认为您的源代码不正确 -
let-statement 在文件中没有意义。 -
@epsilonhalbe:完成。
-
我没有仔细研究过代码,但我的猜测是 memcallback 或 cpucallback 错误(添加类型签名)或
nets=应该是nets <- -
这些部分确实有效。如果您将
nets =替换为上面一行中已注释掉的版本,则一切都可以编译并且工作正常(也可以与 github.com/travitch/taffybar/blob/master/taffybar.hs.example 进行比较)。除了我只有一个硬编码接口这一明显问题。如果我这样做nets <-ghc 会抱怨我不在do块中的解析错误。
标签: haskell