2013-08-25 1 views
0

저는 하스켈을 사용하여 IO에 익숙하지 만 많은 내용을 읽었지만 코드는 여전히 작동하지 않습니다.파일의 줄을 읽고 중간 요소를 정렬하고 반환하십시오.

I 앱이 수행 할 작업 :

  1. 모든 숫자를 각 행을 포함하는 파일의 모든 라인을 (은 File2.txt, file2.txt, ...), 읽기
  2. (1.12345 같은 수레)
  3. 정렬이 모든 선 (문자열 정렬 또는 플로트 정렬 문제가되지 않습니다, 나는 문자열 정렬이 빠른 것 같은데요?)
  4. 목록의 중간 요소를 확인하고이 코드 I입니다

그것을 인쇄 지금까지 해왔다. [중간] 함수가 [문자열]을 전달할 때 잘 작동한다는 것을 확신 할 수 있습니다.

middle :: [a] -> a 
middle xs = (drop ((l - 1) `div ` 2) xs) !! 0 
      where l = length xs 

getSortedMiddleElement :: Int -> String 
getSortedMiddleElement i = do 
    dat <- readFile $ "file" ++ (show i) ++ ".txt" 
    return $ middle $ sort $ lines dat 

나는 "지능 -> 내용"에서 getSortedMiddleElement를 호출하고있는 번호가 URL을 통해 전달되는 중간 요소가 사용자에게 반환해야 기능 (내가 Yesod를 사용). 문자열에서 내용을 가져 오려면 "IO String"이 아닌 "String"이어야합니다. 어떻게 쉽게 얻을 수 있습니까?

미리 감사드립니다.

+2

유형을 'Int -> IO String'으로 변경 한 다음, 예를 들어 다음과 같이 처리한다. 'readFile' 또는 다른 IO 함수. – kqr

+0

고맙습니다. 지금까지 좋은 소리입니다! HTTP 응답을 반환하는'getTestR :: Int -> Handler RepPlain'을 처리하려면 어떻게해야합니까?'getTestR :: Int -> IO Handler RepPlain'이 작동하지 않습니다. ( – sibbl

+0

내가 말할 수 있으면 좋겠지 만, 나는 Yesod의 전문가가 아닙니다 : ( – kqr

답변

5

귀하의 유형 서명 (즉, 그것은 int를 받아 문자열을 반환)하지만 내부는 IO를 수행하는 함수가 순수 말한다! 하스켈은 그러한 함수를 작성하도록 허용하지 않습니다. 파일에서 읽은 내용은 IO 모나드에 영원히 붙어 있습니다. 그게 안전하지 않은 기능은 제외됩니다. Yesod가 크게 IO 기반 프레임 워크이기 때문에이 경우

, 즉, 그렇게 나쁘지 않을에 밝혀졌습니다. 모든 네트워크 트래픽도 IO 모나드에 고정되어 있습니다!

모나드 변압기 스택에있을 때 스택의 각 레벨에서 모나드 계산에 액세스 할 수 있지만 그 중 하나만 입니다. lift을 사용하여 스택의 모나드 한 레이어에서 계산 된 모나드로 계산을 이동합니다. IO이 스택에있는 경우 아무리 많은 레이어가 있더라도 liftIO을 통해 해당 작업에 직접 액세스 할 수 있습니다. 당신이 type T = ReaderT String IO이있는 경우

그래서 당신은 함수 foo :: Int -> T String을 가질 수있다. 이 기능에서 T 모나드에서 작동하며 IO 모나드는 Reader 모나드 기능으로 변환됩니다. 이 문맥에서는 lift readFile라고 말할 수 있으며 IO String 결과 대신 T String 결과가 표시됩니다. 그게 ReaderT 유형으로 싸여진 IO String 일 뿐이므로 IO 모나드를 피하는 것과 같은 까다로운 작업을 수행하지 않았다고 생각하지 마십시오. 즉 약간 혼동하고, 그래서 예를 살펴 보자 수도 :

import Control.Monad.Reader (ReaderT) 
import Control.Monad.Writer (WriterT) 
import Control.Monad.Trans (lift, liftIO) 

type T = ReaderT String IO 
getSortedMiddleElement :: Int -> IO String 

foo :: Int -> T String 
foo n = do 
    str <- lift $ getSortedMiddleElement n --str holds a pure String now 
    lift $ putStrLn str     --get `putStrLn` from IO and pass the String 
    return str        --let's wrap it back in T now 

그러나 무엇 우리가 하나 개 이상의 계층 멀리 IO에서라면? 그것을 시도해 보자.

+0

대단히 감사합니다. 이 상세한 대답!'LiftIO'는 내가 필요한 것입니다. – sibbl