2014-12-06 5 views
2
나는이 나는 역순

하스켈, 간단한 연속

에서 함수 인수를 변경하려면, 이제 CPS 스타일의 스퀘어 기능

-- from : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style 
square :: Int -> Int 
square x = x * x 

square_cps :: Int -> ((Int -> r) -> r) 
square_cps = \cont -> cont (square x) 
-- square_cps 3 print will write '9' out in console 

입니다 간단한 CPS 기능

을 변환하는 힘든 시간을 보내고 있어요

square_cps' :: ((Int -> r) -> r) -> Int 
square_cps' = ? 

불가능합니까? square_cps의 당신의 정의에 약간의 보정

답변

5

첫째 :

square_cps :: Int -> ((Int -> r) -> r) 
square_cps x = \cont -> cont (square x) 
      ^^^ 

은 또한 당신은 쓸 수 있습니다 :

square_cps x cont = cont (square x) 

참고이 유형 서명 만의 함수와 같은 square_cps 보이게하더라도 작동 하나의 논증.

이제 square_cps'의 유형 서명을 사용할 수 없습니다. 그들은 쓰여진대로 r을 반환하는 함수 인 (Int -> r) -> r 중에서 Int을 얻을 수 있음을 의미합니다.

먼저, square_cps에 인수를 플립이 동일한 종류의 서명을 작성하려면 :

square_cps :: Int -> (Int -> r) -> r 
      ^ ^   ^--- result 
       |  \--- second arg 
       \--- first arg 

을 그림과 같이 인수를 식별합니다. 이어서 서명이 상기 제 1 및 제 2 인수 결과 스와핑

square_cps' :: (Int -> r) -> Int -> r 
square_cps' cont x = square_cps x cont 

을 일반적으로 서명 a -> b -> c 즉 오른쪽 함수 타입 생성자 동료 a -> (b -> c) 동일하다.

+0

감사! 이제 왜 작동하지 않는지 이해합니다. 그러나 'square_cps x cont = cont (square x)'는 여전히 나에게 모호합니다. 서명에 기술 된 모든 타입을 취하고'r'을 반환합니다. 즉, foo :: Int -> Int는 foo x y = x + y와 같이 구현 될 수 있습니다. foo는 모든 인수를 취하여 Int를 반환하기 때문입니다. 하지만 그건 내가 컴파일러 오류를 제공합니다. – 1ambda

+2

'foo x y = x + y'를 정의하면'foo'는'Int -> Int'가 아닌'Int -> Int -> Int' 타입을가집니다. ghci를 사용하여 표현식의 유형을 인쇄하는 방법은 [이러한 답변] (http://stackoverflow.com/questions/12659927/using-ghci-to-find-type)을 참조하십시오. – ErikR