今天我遇到了以下问题:
我可以使用名为getScreenWidth的函数( - >我获得IO整数),使用Xlib绑定读取Haskell中的当前屏幕分辨率。到目前为止这是有效的。
现在我想将该值用作桌面环境插件(xmonad)的标签。插件基础结构只允许将“WorkspaceId”(基本上是整数)映射到String的函数。
...
-- Constructor for PrettyPrint:
ppCurrent :: WorkspaceId -> String
...
目前我正在使用自己的函数将ID映射到String,该字符串正常工作:
myPPCurrent :: WorkspaceId -> String
myPPCurrent x = "Desktop: " ++ show x
输出符合预期“桌面:1”(或我正在使用的任何ID)。
现在我希望它是“Desktop:1(1680px)”,其中1680等于getScreenWidth的返回值。
我的问题: getScreenWidth返回IO Integer,所以我不能简单地使用,
myPPCurrent x = do
y <- getScreenWidth
return "Desktop: " ++ show x ++ show y
因为我的返回类型不是String。谷歌告诉我,我无法在Haskell中将“IO Integer”转换为“Integer”,所以我真的不知道如何在使用时保持原型/构造函数(但Haskell称之为)“WorkspaceId - &gt; String”生成该字符串的“IO Integer”。
这甚至可能吗?如果是这样,怎么样?
答案 0 :(得分:4)
我从未使用过XMonad:我的答案基于Haskell的一般知识以及我在互联网上发现的内容,只需2分钟。
无论如何,我假设某个地方有main
来调用xmonad
。
main = xmonad myConfig
或者
main = xmonad XConfig {
normalBorderColor = "#8080ff",
-- etc
或者其他什么。我们来看看类型。
main :: IO ()
xmonad :: (LayoutClass l Window, Read (l Window)) => XConfig l -> IO ()
myConfig :: XConfig l -- whatever type `l` is
现在假设代替myConfig
,我们有
makeMyConfig :: IO (XConfig l) -- I still don't know what `l` is
makeMyConfig
不是配置---它会在运行时进行配置,可能取决于来自磁盘的文件,时间或屏幕分辨率......你可以这样使用它:
main = do
config <- makeMyConfig
xmonad config
重点在于,因为我们现在使用的XConfig l
来自IO (XConfig l)
,所以它可以合并String
s IO String
和Integer
1}}来自IO Integer
s等。这样您就可以在配置中使用getScreenWidth
了。
答案 1 :(得分:3)
一旦你进入IO monad就不能离开它,所以你需要返回IO String
而不是String
,例如
myPPCurrent :: WorkspaceId -> Integer -> String
myPPCurrent x = "Desktop: " ++ show x ++ show y
getWorkspaceName :: WorkspaceId -> IO String
getWorkspaceName id = do
w <- getScreenWidth
return $ myPPCurrent id w