如何在递归函数中使用Control.Monad.Cont? [英] How to use Control.Monad.Cont in a recursive function?

查看:156
本文介绍了如何在递归函数中使用Control.Monad.Cont?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为此问题提供了答案,并且想到了使用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
   |   

但这对我来说没有意义.为什么我有a2m a2?我期望ab属于同一类型.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆