2013-03-12 3 views
1

저는 하스켈의 멍청이이고, 지금은 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) 

실제로 가능합니까? 그렇다면 어떻게? 나는 그 디렉토리에서 작동하고 싶지 않다. 나는 그저 길을 String으로 만들고 싶어서 죽이려한다.

오류는 다음 IO 모나드가 전혀 제거되지 것처럼

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) 

나에게 보인다.

업데이트 : 괜찮습니다. IOs 규칙에 적응하는 방법을 배울 것이며 그때까지는 하드 코딩 된 내용을 유지하고 적절한 비트를 대체 할 스크립트로 구성 파일을 복제 할 것입니다.

답변

5

당신의 getIcongetHomeDirectory는 IO는 않기 때문에, 잘못된 유형이 있습니다

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

하스켈 부작용이 코드를 구별하는 것을 기억 - 유형 IO를 통해 - 같은 하드 디스크를 읽는 등을.

그래서 발신자가 너무 IO에있을 것입니다 :

main = do 
    s <- getIcon "foo" 
    .. now you have a regular string 's' ... 
+0

예, IO 비트를 알고 있습니다. 문제가되는 부분입니다. 리턴 된 IO String이 일반 문자열로 필요합니다. 그 이유는 구성에서 기대하는 것이기 때문입니다. 그래도 코드가 다른 것을 이해하는 데 도움이되었습니다. $ – Erius

+3

@Erius로 반환하고 반환하십시오 'IO String -> String' 유형의 (안전한) 하스켈 함수가 없습니다. 'IO'에서 일어나는 일은 'IO'에 머물러 있습니다. –

1

당신이 지점에서 코드를 변경할 수는 getIcon를 호출하고 어디?

당신이 그것을 호출하기 전에 홈 디렉토리를 얻을 수 있다면, 당신은

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

등을 할 수있는 다음

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

그냥 (그것뿐만 아니라 IO에 가정)에서 전화 할 때마다 최후의 수단을 지적하기 위해 아무 것도 작동하지 않는다면 unsafePerformIO이 있습니다. 그러나 실제로 그것을 사용하지 않아야합니다. (일반적으로 눈살을 찌푸린듯한 느낌입니다.) 그래서 나는 당신을 너무 많이 도울 수 없습니다.

+1

'unsafePerformIO'는 매우 특별한 목적을위한 특별한 도구이며 필요하지 않습니다 (필요할 경우 알 수 있습니다). –

+0

음 * 나는 * 필요하지 않습니다 ... 그냥 옵션을 제공합니다. 내 대답은 이미 편집에 비추어 어리석은 짓이다. 중요한 멍청한 순간이 내 몫이야. – tredontho

1

다른 모나드에서 "벗어날"수 있지만 IO 모나드에서 벗어날 수는 없습니다.

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 값 랩을 해제 할 수있다 : 당신의 Xmonad 구성 파일에서 이런 식으로 뭔가 당신이 원하는 아마. 홈 디렉토리는 특히 자주 변경되지 않기 때문에 합리적인 후보입니다.컴파일시에 문자열로 홈 디렉토리를 얻기위한 템플릿 하스켈 솔루션은 다음과 같이 구분 될 수 있습니다

{-# LANGUAGE TemplateHaskell #-} 
module HomeDirectory where 

import Language.Haskell.TH 
import System.Directory 

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

이 템플릿 하스켈, 비록 악명 까다로운 짐승임을 경고합니다. 이 예제는 충분히 간단하지만 복잡하고 혼란 스러울 수 있습니다.