2014-05-14 4 views
0

나는 (콜백) 함수를 전달하는 C 함수와 상호 작용하며 매번 다른 매개 변수로 호출합니다.콜백에서 값을 목록으로 누적하는 기능적인 방법은 무엇입니까?

나는 하스켈로 수입하고 지금은 이런 걸 (I 물론, 그것을 단순화했습니다)이 : 나는 fn에 전달 된 모든 번호의 목록을 만들고 싶어

countToFive :: (Int -> IO()) -> IO() 
countToFive fn = do fn 1; fn 2; fn 3; fn 4; fn 5 

을; 이 서명 뭔가 :

counting :: IO [Int] 

[1,2,3,4,5]의 결과에 의지 위의 예 (물론, IO를 수행)이다.

counting의 필수 접근 방식은 변경 가능한 목록을 만들고 모든 호출에 대해 변경 가능한 목록에 매개 변수를 삽입 한 다음 목록을 반환하는 함수로 countToFive을 호출하는 것입니다.

기능적 방법은 무엇입니까?

+0

줄 끝의'return()'은 100 % 중복됩니다. – Carl

+1

귀하의 긴급한 버전을 잘 모르겠습니다. 컴파일 타임에 '1..5'라는 숫자가 알려 지거나 런타임에 어딘가에 생성 되는가? 런타임 인 ​​경우'IO Int' 유형의 함수를 가지고있어 다음 번호를 생성하기 위해 반복적으로 사용하려면'fn'을 입력하십시오. 내 질문에 "왜 count 'fn = mapM_ fn [1..5] >> return [1..5]'또는'fn' 수정자를 제공해야하는지 생각해보십시오. applyAndReturn :: (a -> (applyAndReturn fn) [1..5]'? "와 같이 정의 된 IO() -> a -> IO a' – AndrewC

+0

아니면 하나의'fn'을 setter :: Int-> IO()'와 이에 상응하는 getter :: :: IO [Int]'로 정의하고 싶습니까? 그렇다면 질문을 편집하여''fn'과'counting'을 정의하여''countToFive fn >> counting''이'[a, 2,3,4,5]'를 반환하도록하는 방법을 묻습니다. – AndrewC

답변

6

정확히 똑같은 방식으로합니다. IO 모나드에서 너무 깊게 살면 많은 일들이 명령형 사촌과 같이 많은 것을 느낄 것입니다.

import Data.IORef 

counting :: ((Int -> IO()) -> IO()) -> IO [Int] 
counting fun = do 
    store <- newIORef [] 
    fun (\new -> modifyIORef store (new:)) 
    readIORef store 

참고 countToFive의 종류의 함수를 파라미터 위에 counting 오히려 고차 함수 유형의 용도. 더욱 마음을 굽히는 경험을 위해이 방법은 "연속 통과 스타일"과 일치한다는 점에 흥미로운 점이 있습니다. 매우 실질적인 의미에서 countToFive은 정수 목록을 "포함"하며 단순히 "꺼내기"라는 까다로운 방법이 있습니다.

+0

오랫동안 'IORef'와 같은 것을 찾고있었습니다! 정말 고마워요. – MasterMastic

관련 문제