Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8840785
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T10:32:44+00:00 2026-06-14T10:32:44+00:00

In Haskell Wiki’s Recursion in a monad there is an example that is claimed

  • 0

In Haskell Wiki’s Recursion in a monad there is an example that is claimed to be tail-recursive:

f 0 acc = return (reverse acc)
f n acc = do
    v  <- getLine
    f (n-1) (v : acc)

While the imperative notation leads us to believe that it is tail-recursive, it’s not so obvious at all (at least to me). If we de-sugar do we get

f 0 acc = return (reverse acc)
f n acc = getLine >>= \v -> f (n-1) (v : acc)

and rewriting the second line leads to

f n acc = (>>=) getLine (\v -> f (n-1) (v : acc))

So we see that f occurs inside the second argument of >>=, not in a tail-recursive position. We’d need to examine IO‘s >>= to get an answer.
Clearly having the recursive call as the last line in a do block isn’t a sufficient condition a function to be tail-recursive.


Let’s say that a monad is tail-recursive iff every recursive function in this monad defined as

f = do
    ...
    f ...

or equivalently

f ...  =  (...) >>= \x -> f ...

is tail-recursive. My question is:

  1. What monads are tail-recursive?
  2. Is there some general rule that we can use to immediately distinguish tail-recursive monads?

Update: Let me make a specific counter-example: The [] monad is not tail-recursive according to the above definition. If it were, then

f 0 acc = acc
f n acc = do
    r <- acc
    f (n - 1) (map (r +) acc)

would have to be tail-recursive. However, desugaring the second line leads to

f n acc = acc >>= \r -> f (n - 1) (map (r +) acc)
        = (flip concatMap) acc (\r -> f (n - 1) (map (r +) acc))

Clearly, this isn’t tail-recursive, and IMHO cannot be made. The reason is that the recursive call isn’t the end of the computation. It is performed several times and the results are combined to make the final result.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T10:32:45+00:00Added an answer on June 14, 2026 at 10:32 am

    A monadic computation that refers to itself is never tail-recursive. However, in Haskell you have laziness and corecursion, and that is what counts. Let’s use this simple example:

    forever :: (Monad m) => m a -> m b
    forever c' = let c = c' >> c in c
    

    Such a computation runs in constant space if and only if (>>) is nonstrict in its second argument. This is really very similar to lists and repeat:

    repeat :: a -> [a]
    repeat x = let xs = x : xs in xs
    

    Since the (:) constructor is nonstrict in its second argument this works and the list can be traversed, because you have a finite weak-head normal form (WHNF). As long as the consumer (for example a list fold) only ever asks for the WHNF this works and runs in constant space.

    The consumer in the case of forever is whatever interprets the monadic computation. If the monad is [], then (>>) is non-strict in its second argument, when its first argument is the empty list. So forever [] will result in [], while forever [1] will diverge. In the case of the IO monad the interpreter is the very run-time system itself, and there you can think of (>>) being always non-strict in its second argument.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In Haskell, is there a way to restrict a monad M a so that
In Haskell, lifted type products mean that there's a semantic difference between (a,b,c) and
The Haskell wiki states that you should use Cabal as your build system. However,
Following an example in http://en.wikibooks.org/wiki/Haskell/Beginning Prelude> let abs x = if x < 0
The Haskell wiki shows that you need to both set a compilation flag and
Im trying to understand what a functor is, i found this tutorial/example: http://en.wikibooks.org/wiki/Haskell/Solutions/Applicative_Functors data
since Haskell has such expressive type system, is there something supported directly that we
I've seen mentioned that ListT is a classic example of a buggy monad transformer
On the Haskell wiki I read that this : fib = let fib' 0
I have followed the tutorial on the Haskell wiki about i mplementing an IRC

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.