我是Haskell noob,目前只使用它来配置xmonad。
我想将我的配置放入git仓库,因为我不想硬编码我的家庭目录来抓取我的图标。
我检查了一下 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规则,在此之前我将保持硬编码并使用将替换相应位的脚本克隆配置文件。
答案 0 :(得分: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' ...
答案 1 :(得分:1)
您可以在调用getIcon
时更改代码吗?
如果您在调用之前可以获取主目录,则可以执行
getIcon :: String -> String -> String
getIcon out hd = ( "^i("++hd++".xmonad/dzen2/"++out )
然后你在哪里打电话(假设它也在IO
)
someIOFunction = do
things
....
hd <- getHomeDirectory
getIcon out hd
只是指出最后的手段,如果没有其他工作,有unsafePerformIO
,但我从来没有真正使用它(我觉得它通常不赞成),所以我不能在那里帮助你太多了。
答案 2 :(得分: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
答案 3 :(得分:0)
使用Template Haskell可以在编译时解包某些IO
值。一个人的主目录是一个合理的候选人,因为它不会经常变化。用于在编译时将主目录作为字符串获取的模板Haskell解决方案可能编码如下:
{-# LANGUAGE TemplateHaskell #-}
module HomeDirectory where
import Language.Haskell.TH
import System.Directory
myHome :: String
myHome = $(LitE . StringL `fmap` runIO getHomeDirectory)
请注意,模板Haskell是一个臭名昭着的棘手野兽。这个例子很简单,但很容易让人感到复杂和困惑。