2013-03-12 102 views
1

我是一个Haskell noob,目前只能用它来配置xmonad。如何将Haskell System.Directory getHomeDirectory转换为常规字符串?

我想把我的配置放入一个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单子都没有。

更新: 好的。我将学习如何适应IO规则,直到那时我会保持硬编码并用一个脚本来克隆配置文件,该脚本将替换适当的位。

回答

5

getIcon类型错误,因为getHomeDirectory确实IO:

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' ... 
+0

是的,我知道IO位,这是给我的麻烦。我需要返回的IO字符串作为常规字符串,因为这就是配置所期望的。不过,你的代码确实帮助我理解了别的东西。做,并返回$ – Erius 2013-03-12 15:12:00

+3

@Erius没有(安全)Haskell函数的类型'IO字符串 - >字符串'。 'IO'在'IO'中停滞了。 – 2013-03-12 15:50:07

1

你能在点更改代码,在那里你调用getIcon

如果你可以调用它之前获得的主目录,你可以做

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

,然后无论你是从(假设它是在IO为好)

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

只调用指出一个最后的手段,如果没有其他的工作,有unsafePerformIO,但我从来没有真的必须使用它(我觉得它通常是皱眉),所以我不能帮你太多。

+1

'unsafePerformIO'是一个非常特殊的用途的特殊工具,你不需要它(你会知道如果你需要它)。 – 2013-03-12 17:54:33

+0

好吧*我*不需要它......只是给予选择。根据dons的编辑,我的回答已经很愚蠢。主要是我的时刻。 – tredontho 2013-03-12 18:40:22

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 
0

有可能在编译时解开某些IO值,使用模板哈斯克尔。一个人的主目录是一个合理的候选人,因为它并不经常改变。用于获取主目录是在编译时一个字符串模板Haskell的解决方案可能是编码是这样的:

{-# LANGUAGE TemplateHaskell #-} 
module HomeDirectory where 

import Language.Haskell.TH 
import System.Directory 

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

被警告,模板Haskell是出了名的棘手的野兽,虽然。这个例子很简单,但它很容易导致复杂和混乱。