1

我是 Haskell 菜鸟,目前只用它来配置 xmonad。

我想把我的配置放到一个 git repo 中,因为我不想硬编码我的主目录来获取我的图标。

我查看了 http://www.haskell.org/haskellwiki/How_to_get_rid_of_IO 但我太无知了,无法理解。

hd h = h =<< getHomeDirectory

getIcon::String -> String
getIcon out = ( "^i("++hd++".xmonad/dzen2/"++out )

这真的可能吗?如果是这样,怎么做?我不想对目录进行操作,我只想要路径,作为一个字符串,它正在杀死我。

错误是:

Couldn't match expected type `[Char]'
            with actual type `(FilePath -> IO b0) -> IO b0'
In the first argument of `(++)', namely `hd'
In the second argument of `(++)', namely
  `hd ++ ".xmonad/dzen2/" ++ out'
In the expression: ("^i(" ++ hd ++ ".xmonad/dzen2/" ++ out)

在我看来, IO monad 根本没有被删除。

更新:好的。我将学习如何适应 IO 规则,在此之前我将保持硬编码并使用将替换适当位的脚本克隆配置文件。

4

4 回答 4

6

getIcon有错误的类型,因为getHomeDirectoryIO:

getIcon :: String -> IO String
getIcon out = do
     hd <- getHomeDirectory
     return $ "^i(" ++ hd ++ ".xmonad/dzen2/" ++ out

请记住,Haskell 通过类型区分具有副作用的代码(例如读取硬盘)IO

所以调用者也会在 IO 中:

main = do
    s <- getIcon "foo"
    .. now you have a regular string 's' ...
于 2013-03-12T15:06:24.243 回答
1

你可以在你打电话的地方更改代码getIcon吗?

如果你可以在调用它之前获取主目录,你可以这样做

getIcon :: String -> String -> String
getIcon out hd = ( "^i("++hd++".xmonad/dzen2/"++out )

然后无论你从哪里打电话(假设它IO也在)

someIOFunction = do
    things
    ....
    hd <- getHomeDirectory
    getIcon out hd

只是为了指出最后的手段,如果没有其他方法,有unsafePerformIO,但我实际上从未使用过它(而且我觉得它通常不受欢迎),所以我在那里帮不了你太多。

于 2013-03-12T15:56:28.777 回答
1

您可以“突破”其他 monad,但不能突破 IO monad。Xmonad 配置文件中的类似内容可能是您想要的:

getIcon::String -> String
getIcon out = ( "^i("++hd++".xmonad/dzen2/"++out )

main =
   h <- getHomeDirectory
   let myIcon = getIcon "Firefox"
   xmonad $ desktopConfig . . . -- use myIcon somewhere in this expression
于 2013-03-13T14:07:25.663 回答
0

IO可以在编译时使用 Template Haskell解包某些值。一个人的主目录是一个合理的候选者,因为它不会经常更改。用于在编译时将主目录作为字符串获取的 Template Haskell 解决方案可能编码如下:

{-# LANGUAGE TemplateHaskell #-}
module HomeDirectory where

import Language.Haskell.TH
import System.Directory

myHome :: String
myHome = $(LitE . StringL `fmap` runIO getHomeDirectory)

不过请注意,Template Haskell 是出了名的狡猾的野兽。这个例子很简单,但很容易变得复杂和混乱。

于 2013-04-28T12:25:03.893 回答