Haskell, просто продължение

Трудно ми е да конвертирам проста CPS функция

Това е квадратна функция в стил 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

Сега бих искал да променя аргументите на функцията в обратен ред

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

Невъзможно ли е?


person 1ambda    schedule 06.12.2014    source източник


Отговори (1)


Първо малка корекция на вашето определение за square_cps:

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

Като алтернатива можете да напишете:

square_cps x cont = cont (square x)

Имайте предвид, че това работи, въпреки че сигнатурата на типа прави square_cps да изглежда като функция само на един аргумент.

Сега сигнатурата на типа за square_cps' не може да работи. Начинът, по който е написан, означава, че можете да получите Int от (Int -> r) -> r, което е функция, която връща r.

За да обърнете аргументите към square_cps, първо напишете този еквивалентен тип подпис:

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

и идентифицирайте аргументите, както е показано. След това размяната на първия и втория аргумент води до този подпис:

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

Като цяло сигнатурата a -> b -> c е еквивалентна на a -> (b -> c), т.е. конструкторът на типа функция се асоциира отдясно.

person ErikR    schedule 06.12.2014
comment
Благодаря! Сега разбирам защо не работи. Но „square_cps x cont = cont (square x)“ все още е двусмислено за мен. Той приема всички типове, описани в подписа, и връща r. Това означава, че foo :: Int -› Int може да бъде имплементирано като foo x y = x + y. тъй като foo също приема всички аргументи и връща Int. Но това ми дава грешка на компилатора. - person 1ambda; 06.12.2014
comment
Когато дефинирате: foo x y = x + y, тогава foo има тип Int -> Int -> Int, а не Int -> Int. Вижте тези отговори за това как да използвате ghci за отпечатване на типа на израз. - person ErikR; 06.12.2014