1

今天我遇到了以下问题:

我可以使用名为 getScreenWidth 的函数使用 Xlib 绑定​​读取 Haskell 中的当前屏幕分辨率(--> 我得到一个 IO 整数)。到目前为止,这是有效的。

现在我想将该值用作我的桌面环境 (xmonad) 插件的标签。插件基础结构只允许将“WorkspaceId”(基本上是一个整数)映射到字符串的函数。

...
-- Constructor for PrettyPrint: 
ppCurrent :: WorkspaceId -> String
...

目前我正在使用自己的函数将 ID 映射到字符串,该函数正在工作:

myPPCurrent :: WorkspaceId -> String
myPPCurrent x = "Desktop: " ++ show x

输出如预期的那样“桌面:1”(或我使用的任何 ID)。

现在我希望它是“桌面:1 (1680px)”,其中 1680 等于 getScreenWidth 的返回值。

我的问题: getScreenWidth 返回 IO Integer,所以我不能简单地使用,

myPPCurrent x = do
    y <- getScreenWidth
    return "Desktop: " ++ show x ++ show y

因为我的返回类型不是字符串。谷歌告诉我,我无法在 Haskell 中将“IO Integer”转换为“Integer”,所以我真的不知道如何在使用“IO Integer”生成该字符串。

这甚至可能吗?如果是这样,怎么做?

4

2 回答 2

4

我从未使用过 XMonad:我将这个答案基于一般的 Haskell 知识以及我在 2.5 分钟内在互联网上找到的内容。

无论如何,我假设你在某个地方有一个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我们现在使用的 s 是从 an 派生的IO (XConfig l),它可以合并String从 s 派生的IO Strings 和Integer从 s 派生的IO Integers 等。所以这就是你在getScreenWidth配置中使用的方法。

于 2013-04-24T18:33:37.627 回答
3

进入 IO monad 后,您将无法离开,因此您需要返回 anIO String而不是 a Stringeg

myPPCurrent :: WorkspaceId -> Integer -> String
myPPCurrent x = "Desktop: " ++ show x ++ show y

getWorkspaceName :: WorkspaceId -> IO String
getWorkspaceName id = do
    w <- getScreenWidth
    return $ myPPCurrent id w
于 2013-04-24T17:50:13.570 回答