如何在递归函数中使用Control.Monad.Cont? [英] How to use Control.Monad.Cont in a recursive function?
问题描述
我为此问题提供了答案,并且想到了使用Cont
monad的想法.我对Haskell不够了解,无法解释为什么该程序不起作用
I was providing an answer to this question and an idea came to me to use Cont
monad. I don't know Haskell enough to explain why this program doesn't work
import Control.Monad.Cont
fib1 n = runCont (slow n) id
where
slow 0 = return 0
slow 1 = return 1
slow n = do
a <- slow (n - 1)
b <- slow (n - 2)
return a + b
main = do
putStrLn $ show $ fib1 10
错误-
main.hs:10:18: error:
• Occurs check: cannot construct the infinite type: a2 ~ m a2
• In the second argument of ‘(+)’, namely ‘b’
In a stmt of a 'do' block: return a + b
In the expression:
do a <- slow (n - 1)
b <- slow (n - 2)
return a + b
• Relevant bindings include
b :: a2 (bound at main.hs:9:7)
a :: a2 (bound at main.hs:8:7)
slow :: a1 -> m a2 (bound at main.hs:5:5)
|
10 | return a + b
|
但这对我来说没有意义.为什么我有a2
和m a2
?我期望a
和b
属于同一类型.
But this doesn't make sense to me. Why do I have a2
and m a2
? I'm expecting a
and b
to be of the same type.
这让我很烦,因为同一程序在JavaScript中工作得很好.也许Haskell需要一个类型提示?
It's bugging me because the same program works just fine in JavaScript. Maybe the Haskell one needs a type hint?
const runCont = m => k =>
m (k)
const _return = x =>
k => k (x)
const slow = n =>
n < 2
? _return (n)
: slow (n - 1) (a =>
slow (n - 2) (b =>
_return (a + b)))
const fib = n =>
runCont (slow(n)) (console.log)
fib (10) // 55
推荐答案
return a + b
解析为(return a) + b
,而您想要return (a + b)
.请记住,函数应用程序的绑定比任何infix运算符都更紧密.
return a + b
parses as (return a) + b
, whereas you wanted return (a + b)
. Remember that function application binds tighter than any infix operator.
(写return $ a + b
也很常见,这等同于同一件事)
(It's also common to write return $ a + b
, which amounts to the same thing)
这篇关于如何在递归函数中使用Control.Monad.Cont?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!