내 도구 상자에 Haskell을 추가하여 Real World Haskell을 통해 작업하고 있습니다. 처리hGetContents는 어떻게 메모리 효율성을 달성합니까?
공지 사항
hGetContents
을 것을 : 저자가 말을 계속이 코드 샘플에 따라import System.IO import Data.Char(toUpper) main :: IO() main = do inh <- openFile "input.txt" ReadMode outh <- openFile "output.txt" WriteMode inpStr <- hGetContents inh let result = processData inpStr hPutStr outh result hClose inh hClose outh processData :: String -> String processData = map toUpper
: the section on
는,이 예를 건너 왔어요 우리 모두를위한 독서. 또한hGetContents
의 입력과 출력의 장에서processData
을 살펴보십시오. 그것은 부작용이 없으며 호출 될 때마다 항상 동일한 결과를 반환하기 때문에 순수한 함수입니다. 을 알 필요가 없으며을 입력 할 수 없습니다.이 경우 입력이 파일에서 지연적으로 읽히고 있습니다. 디스크의 20 문자 리터럴 또는 500GB 데이터 덤프로 완벽하게 작동 할 수 있습니다.
내 질문은 (NB 강조는 내 꺼야) : hGetContents
을 수행 또는 그 결과 값이 메모리 효율성없이 달성하는 방법 -이 예에서는 - processData
은 "말할 수있는"여전히 모든 혜택을 유지하는 순수 코드 (즉, processData
), 특히 메모로 생성됩니까?
<- hGetContents inh
inpStr
이
processData
가 받아들이는 정확히 유형 유형
String
의 값에 바인딩 된 문자열을 반환합니다. 그러나 Real World Haskell의 저자를 올바르게 이해한다면이 문자열은 다른 문자열과 완전히 같지 않습니다. 메모리에 완전히로드되지 않습니다 (또는 완전히 평가되지 않은 문자열이있는 경우 완전히 평가됩니다.). .)
processData
로 전화를 걸 때까지.
따라서, 내 질문을하는 또 다른 방법은 다음과 같습니다 inpStr
가 완전히 processData
호출시 메모리로 평가되거나로드되지 않는 경우, 다음 방법이없이, processData
에 memoized 호출이있는 경우 조회 할 수 있습니다 먼저 완전히 inpStr
을 평가합니까?
String
유형의 인스턴스가 각각 다르게 동작하지만이 추상화 수준에서 구분할 수 없습니까?
답변 해 주셔서 감사합니다. 호기심을 만족시키기 위해 GHC에서 메모 작성을 수행하는지 또는 방금 언급 한 이유로 최적화를 수행하지 않는지 알려주시겠습니까? 원자적인 인수 (즉, 목록과 같은 데이터 구조가 없음)가있는 함수를 메모하는 것이 구현하기가 훨씬 쉽다는 것을 알 것입니다. – Marcel
GHC는 함수의 자동 메모를 수행하지 않습니다. 그러나 변수의 값은 한 번만 계산됩니다. – kqr
@MarcelOomens : 일반적으로 대답하기는 어렵지만 간단한 열거 형의 분기 (예 :'data Foo = Foo | Bar | Baz')는 종종 메모 된 호출로 바뀝니다. 이것은 일반적인 GHC 최적화 변환의 결과 인 것 같습니다. 특별한 지원이 있다고 생각하지 않습니다. –