2013-04-24 4 views
1

오늘을 계산하는 IO 정수를 사용하는 동안 문자열을 반환 :하스켈, 해당 문자열에게 나는 다음과 같은 문제로 실행

내가 getScreenWidth (라는 함수를 사용 Xlib를 바인딩에 사용 하스켈의 현재 화면 해상도 읽을 수 있습니다 -> I을 IO 정수를 얻는다). 이것은 지금까지 일하고있다.

이제이 값을 내 데스크톱 환경 (xmonad)의 플러그인 레이블로 사용하고 싶습니다. 플러그인 인프라는 "WorkspaceId"(기본적으로 정수)를 문자열로 매핑하는 함수 만 허용합니다.

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

출력은 예상 "데스크톱 : 1"로되어있다 (또는 무엇이든 ID 난에 오전

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

은 현재 내가 근무하는 문자열에 ID를 매핑하는 내 자신의 기능을 사용하고 있습니다).

이제는 "Desktop : 1 (1680px)"이되어야합니다. 여기서 1680은 getScreenWidth의 반환 값과 같습니다.

내 문제 : getScreenWidth는 IO 정수를 반환, 그래서 간단하게 사용할 수 없습니다

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

난 이후 반환 유형은 문자열이 아닙니다. Google은 Haskell에서 "IO Integer"를 "Integer"로 변환 할 수 없다는 사실을 알려 주었기 때문에 프로토 타입/생성자 (Haskell이 호출 함)를 "WorkspaceId -> String"으로 유지할 수있는 단서가 없습니다. "IO Integer"는 해당 문자열을 생성합니다.

전혀 가능합니까? 그렇다면 어떻게?

+1

모나드 안에 있어야합니다. – SLaks

답변

3

IO Monad를 사용하면 퇴장 할 수 없으므로 String 대신 IO String을 반환해야합니다.

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

getWorkspaceName :: WorkspaceId -> IO String 
getWorkspaceName id = do 
    w <- getScreenWidth 
    return $ myPPCurrent id w 
4

저는 XMonad를 한번도 사용하지 않았습니다 : 저는 하스켈의 일반적인 지식과이 2 분 30 초 만에 인터넷에서 발견 한이 답변을 기반으로합니다.

어쨌든 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 

이제 우리는

makeMyConfig

makeMyConfig :: IO (XConfig l) -- I still don't know what `l` is 
가 구성되지 않습니다이 대신 myConfig의 가정 --- 잠재적 디스크에서 파일에 따라 런타임에 구성을 만들 것입니다 뭔가,의, 또는 시간 또는 화면 해상도 ....당신은 너무처럼 사용

main = do 
    config <- makeMyConfig 
    xmonad config 

그리고 그 점은 우리가 지금 사용하고있는 XConfig lIO (XConfig l)에서 파생되기 때문에,이 등 IO Integer의에서 파생 IO String들과 Integer의에서 파생 된 String의를 통합 할 수 있다는 것입니다 따라서 구성에 getScreenWidth을 사용하십시오.