Understanding Haskell callCC examples - haskell

I am having trouble understanding the answers to a previous question. I'm hoping that an explanation of the following will clarify things. The following example comes from fpcomplete
import Control.Monad.Trans.Class
import Control.Monad.Trans.Cont
main = flip runContT return $ do
lift $ putStrLn "alpha"
(k, num) <- callCC $ \k -> let f x = k (f, x)
in return (f, 0)
lift $ putStrLn "beta"
lift $ putStrLn "gamma"
if num < 5
then k (num + 1) >> return ()
else lift $ print num
The output is
alpha
beta
gamma
beta
gamma
beta
gamma
beta
gamma
beta
gamma
beta
gamma
5
I think I understand how this example works, but why is it necessary to have a let expression in the callCC to "return" the continuation so that it can be used later on. So I tried to directly return the continuation by taking the following simpler example and modifying it.
import Control.Monad.Trans.Class
import Control.Monad.Trans.Cont
main = flip runContT return $ do
lift $ putStrLn "alpha"
callCC $ \k -> do
k ()
lift $ putStrLn "uh oh..."
lift $ putStrLn "beta"
lift $ putStrLn "gamma"
This prints
alpha
beta
gamma
And I modified it to the following
import Control.Monad.Trans.Class
import Control.Monad.Trans.Cont
main = flip runContT return $ do
lift $ putStrLn "alpha"
f <- callCC $ \k -> do
lift $ putStrLn "uh oh..."
return k
lift $ putStrLn "beta"
lift $ putStrLn "gamma"
The idea being that the continuation would get returned as f and be unused in this test example which I would expect to print
uh oh...
beta
gamma
But this example doesn't compile, why can't this be done?
Edit: Consider the analgous example in Scheme. As far as I know Scheme wouldn't have a problem, is that correct?, but why?.

As the others have written the last example does not typecheck due to an infinite type.
#augustss proposed another way of solving this problem:
You can also make a newtype to wrap the infinite (equi-)recursive type into a (iso-)recursive newtype. – augustss Dec 12 '13 at 12:50
Here's my take at it:
import Control.Monad.Trans.Cont
import Control.Monad.Trans.Class
data Mu t = In { out :: t (Mu t) }
newtype C' b a = C' { unC' :: a -> b }
type C b = Mu (C' b)
unfold = unC' . out
fold = In . C'
setjmp = callCC $ (\c -> return $ fold c)
jump l = unfold l l
test :: ContT () IO ()
test = do
lift $ putStrLn "Start"
l <- setjmp
lift $ putStrLn "x"
jump l
main = runContT test return
I think this is what #augustss had in mind.

Looking at your examples in reverse order.
The last example does not typecheck due to an infinite type. Looking at the type of callCC, it is ((a -> ContT r m b) -> ContT r m a) -> ContT r m a. If we try to return the continuation we return something of type ContT r m (a -> ContT r m b). This means we get the type equality constraint a ~ (a -> ContT r m b), which means a has to be an infinite type. Haskell does not allow these (in general, for good reason - as far as I can tell the infinite type here would be something along the lines of, supply it an infinite order function as an argument).
You don't mention whether there's anything you're confused about in the second example, but. The reason that it does not print "uh oh..." is because the ContT action produced by k (), unlike many ContT actions does not use the following computation. This is the difference between the continuations and just normal functions which return ContT actions (disclaimer, any function could return a ContT action like this, but in general). So, when you follow the k () up with a print, or anything else, it is irrelevant, because the k () just discards the following actions.
So, the first example. The let binding here is actually only used to mess around with the parameters to k. But by doing so we avoid an infinite type. Effectively, we do some recursion in the let binding which is related to the infinite type we got before. f is a little bit like a version of the continuation with the recursion already done.
The type of this lambda we pass to callCC is Num n => ((n -> ContT r m b, n) -> ContT r m b) -> ContT r m (n -> ContT r m b, n). This does not have the same infinite type problem that your last example has, because we messed around with the parameters. You can perform a similar trick without adding the extra parameter by using let bindings in other ways. For example:
recur :: Monad m => ContT r m (ContT r m ())
recur = callCC $ \k -> let r = k r in r >> return r
This probably wasn't a terribly well explained answer, but the basic idea is that returning the continuation directly will create an infinite type problem. By using a let binding to create some recursion inside the lambda you pass to callCC, you can avoid this.

The example executes in the ContT () IO monad, the Monad allowing continuations that result in () and some lifted IO.
type ExM a = ContT () IO a
ContT can be an incredibly confusing monad to work in, but I've found that Haskell's equational reasoning is a powerful tool for disentangling it. The remainder of this answer examines the original example in several steps, each powered by syntactic transforms and pure renamings.
So, let's first examine the type of the callCC part—it's ultimately the heart of this entire piece of code. That chunk is responsible for generating a strange kind of tuple as its monadic value.
type ContAndPrev = (Int -> ExM (), Int)
getContAndPrev :: ExM ContAndPrev
getContAndPrev = callCC $ \k -> let f x = k (f, x)
in return (f, 0)
This can be made a little bit more familiar by sectioning it with (>>=), which is exactly how it would be used in a real context—any do-block desugaring will create the (>>=) for us eventually.
withContAndPrev :: (ContAndPrev -> ExM ()) -> ExM ()
withContAndPrev go = getContAndPrev >>= go
and finally we can examine that it actually looks like in the call site. To be more clear, I'll desugar the original example a little bit
flip runContT return $ do
lift (putStrLn "alpha")
withContAndPrev $ \(k, num) -> do
lift $ putStrLn "beta"
lift $ putStrLn "gamma"
if num < 5
then k (num + 1) >> return ()
else lift $ print num
Notice that this is a purely syntactic transformation. The code is identical to the original example, but it highlights the existence of this indented block under withContAndPrev. This is the secret to understanding Haskell callCC---withContAndPrev is given access to the entire "rest of the do block" which it gets to choose how to use.
Let's ignore the actual implementation of withContAndPrev and just see if we can create the behavior we saw in running the example. It's fairly tricky, but what we want to do is pass into the block the ability to call itself. Haskell being as lazy and recursive as it is, we can write that directly.
withContAndPrev' :: (ContAndPrev -> ExM ()) -> ExM ()
withContAndPrev' = go 0 where
go n next = next (\i -> go i next, n)
This is still something of a recursive headache, but it might be easier to see how it works. We're taking the remainder of the do block and creating a looping construct called go. We pass into the block a function that calls our looper, go, with a new integer argument and returns the prior one.
We can begin to unroll this code a bit by making a few more syntactic changes to the original code.
maybeCont :: ContAndPrev -> ExM ()
maybeCont k n | n < 5 = k (num + 1)
| otherwise = lift (print n)
bg :: ExM ()
bg = lift $ putStrLn "beta" >> putStrLn "gamma"
flip runContT return $ do
lift (putStrLn "alpha")
withContAndPrev' $ \(k, num) -> bg >> maybeCont k num
And now we can examine what this looks like when betaGam >> maybeCont k num gets passed into withContAndPrev.
let go n next = next (\i -> go i next, n)
next = \(k, num) -> bg >> maybeCont k num
in
go 0 next
(\(k, num) -> betaGam >> maybeCont k num) (\i -> go i next, 0)
bg >> maybeCont (\i -> go i next) 0
bg >> (\(k, num) -> betaGam >> maybeCont k num) (\i -> go i next, 1)
bg >> bg >> maybeCont (\i -> go i next) 1
bg >> bg >> (\(k, num) -> betaGam >> maybeCont k num) (\i -> go i next, 2)
bg >> bg >> bg >> maybeCont (\i -> go i next) 2
bg >> bg >> bg >> bg >> maybeCont (\i -> go i next) 3
bg >> bg >> bg >> bg >> bg >> maybeCont (\i -> go i next) 4
bg >> bg >> bg >> bg >> bg >> bg >> maybeCont (\i -> go i next) 5
bg >> bg >> bg >> bg >> bg >> bg >> lift (print 5)
So clearly our fake implementation recreates the behavior of the original loop. It might be slightly more clear how our fake behavior achieves that by tying a recursive knot using the "rest of the do block" which it receives as an argument.
Armed with this knowledge, we can take a closer look at callCC. We'll again profit by initially examining it in its pre-bound form. It's extremely simple, if weird, in this form.
withCC gen block = callCC gen >>= block
withCC gen block = block (gen block)
In other words, we use the argument to callCC, gen, to generate the return value of callCC, but we pass into gen the very continuation block that we end up applying the value to. It's recursively trippy, but denotationally clear—callCC is truly "call this block with the current continuation".
withCC (\k -> let f x = k (f, x)
in return (f, 0)) next
next (let f x = next (f, x) in return (f, 0))
The actual implementation details of callCC are a bit more challenging since they require that we find a way to define callCC from the semantics of (callCC >>=) but that's mostly ignorable. At the end of the day, we profit from the fact that do blocks are written so that each line gets the remainder of the block bound to it with (>>=) which provides a natural notion of continuation immediately.

why is it necessary to have a let expression in the callCC to "return"
the continuation so that it can be used later on
Thats the exact use of continuation, i.e capture the current execution context and then later use this capture continuation to jump back to that execution context.
It seems that you are confused by the function name callCC, which may be indicating to you that it is calling a continuation BUT actually it is creating a continuation.

Related

Is this syntax as expressive as the do-notation?

The do notation allows us to express monadic code without overwhelming nestings, so that
main = getLine >>= \ a ->
getLine >>= \ b ->
putStrLn (a ++ b)
can be expressed as
main = do
a <- getLine
b <- getLine
putStrLn (a ++ b)
Suppose, though, the syntax allows ... #expression ... to stand for do { x <- expression; return (... x ...) }. For example, foo = f a #(b 1) c would be desugared as: foo = do { x <- b 1; return (f a x c) }. The code above could, then, be expressed as:
main = let a = #getLine in
let b = #getLine in
putStrLn (a ++ b)
Which would be desugared as:
main = do
x <- getLine
let a = x in
return (do
x' <- getLine
let b = x' in
return (putStrLn (a ++ b)))
That is equivalent. This syntax is appealing to me because it seems to offer the same functionality as the do-notation, while also allowing some shorter expressions such as:
main = putStrLn (#(getLine) ++ #(getLine))
So, I wonder if there is anything defective with this proposed syntax, or if it is indeed complete and equivalent to the do-notation.
putStrLn is already String -> IO (), so your desugaring ... return (... return (putStrLn (a ++ b))) ends up having type IO (IO (IO ())), which is likely not what you wanted: running this program won't print anything!
Speaking more generally, your notation can't express any do-block which doesn't end in return. [See Derek Elkins' comment.]
I don't believe your notation can express join, which can be expressed with do without any additional functions:
join :: Monad m => m (m a) -> m a
join mx = do { x <- mx; x }
However, you can express fmap constrained to Monad:
fmap' :: Monad m => (a -> b) -> m a -> m b
fmap' f mx = f #mx
and >>= (and thus everything else) can be expressed using fmap' and join. So adding join would make your notation complete, but still not convenient in many cases, because you end up needing a lot of joins.
However, if you drop return from the translation, you get something quite similar to Idris' bang notation:
In many cases, using do-notation can make programs unnecessarily verbose, particularly in cases such as m_add above where the value bound is used once, immediately. In these cases, we can use a shorthand version, as follows:
m_add : Maybe Int -> Maybe Int -> Maybe Int
m_add x y = pure (!x + !y)
The notation !expr means that the expression expr should be evaluated and then implicitly bound. Conceptually, we can think of ! as being a prefix function with the following type:
(!) : m a -> a
Note, however, that it is not really a function, merely syntax! In practice, a subexpression !expr will lift expr as high as possible within its current scope, bind it to a fresh name x, and replace !expr with x. Expressions are lifted depth first, left to right. In practice, !-notation allows us to program in a more direct style, while still giving a notational clue as to which expressions are monadic.
For example, the expression:
let y = 42 in f !(g !(print y) !x)
is lifted to:
let y = 42 in do y' <- print y
x' <- x
g' <- g y' x'
f g'
Adding it to GHC was discussed, but rejected (so far). Unfortunately, I can't find the threads discussing it.
How about this:
do a <- something
b <- somethingElse a
somethingFinal a b

Use two monads without a transformer

In order to understand how to use monad transformers, I wrote the following code without one. It reads standard input line by line and displays each line reversed until an empty line is encountered. It also counts the lines using State and in the end displays the total number.
import Control.Monad.State
main = print =<< fmap (`evalState` 0) go where
go :: IO (State Int Int)
go = do
l <- getLine
if null l
then return get
else do
putStrLn (reverse l)
-- another possibility: fmap (modify (+1) >>) go
rest <- go
return $ do
modify (+1)
rest
I wanted to add the current line number before each line. I was able to do it with StateT:
import Control.Monad.State
main = print =<< evalStateT go 0 where
go :: StateT Int IO Int
go = do
l <- lift getLine
if null l
then get
else do
n <- get
lift (putStrLn (show n ++ ' ' : reverse l))
modify (+1)
go
My question is: how to do the same in the version without monad transformers?
The problem you're having is that the hand-unrolling of StateT s IO a is s -> IO (s, a), not IO (s -> (s, a))! Once you have this insight, it's pretty easy to see how to do it:
go :: Int -> IO (Int, Int)
go s = do
l <- getLine
if null l
then return (s, s)
else do
putStrLn (show s ++ ' ' : reverse l)
go (s+1)
You'd just need to run the accumulated state computation on every line. This is O(n²) time, but since your first program is already using O(n) space, that's not too terrible. Of course, the StateT approach is superior in pretty much every way! If you really want to do it "by hand" and not pay an efficiency price, just manage the state by hand instead of building a state transformer at all. You're really not getting any benefit by using State instead of Int in the first program.
Maybe this is what you are looking for?
main = print =<< fmap (`evalState` 0) (go get) where
go :: State Int Int -> IO (State Int Int)
go st = do
l <- getLine
if null l
then return (st >>= \_ -> get)
else do
let ln = evalState st 0
putStrLn(show ln ++ ' ' : reverse l)
go (st >>= \_ -> modify (+1) >>= \_ -> get)
The idea here is to make go tail recursive, building up your state computation, which you can then evaluate at each step.
EDIT
This version will bound the size of the state computation to a constant size, although under lazy evaluation, when the previous state computation is forced, we should be able to reuse it without re-evaluating it, so I'm guessing that these are essentially the same...
main = print =<< fmap (`evalState` 0) (go get) where
go :: State Int Int -> IO (State Int Int)
go st = do
l <- getLine
if null l
then return st
else do
let ln = evalState st 0
putStrLn(show ln ++ ' ' : reverse l)
go (modify (\s -> s+ln+1) >>= \_ -> get)

How to increment a variable in functional programming?

How do you increment a variable in a functional programming language?
For example, I want to do:
main :: IO ()
main = do
let i = 0
i = i + 1
print i
Expected output:
1
Simple way is to introduce shadowing of a variable name:
main :: IO () -- another way, simpler, specific to monads:
main = do main = do
let i = 0 let i = 0
let j = i i <- return (i+1)
let i = j+1 print i
print i -- because monadic bind is non-recursive
Prints 1.
Just writing let i = i+1 doesn't work because let in Haskell makes recursive definitions — it is actually Scheme's letrec. The i in the right-hand side of let i = i+1 refers to the i in its left hand side — not to the upper level i as might be intended. So we break that equation up by introducing another variable, j.
Another, simpler way is to use monadic bind, <- in the do-notation. This is possible because monadic bind is not recursive.
In both cases we introduce new variable under the same name, thus "shadowing" the old entity, i.e. making it no longer accessible.
How to "think functional"
One thing to understand here is that functional programming with pure — immutable — values (like we have in Haskell) forces us to make time explicit in our code.
In imperative setting time is implicit. We "change" our vars — but any change is sequential. We can never change what that var was a moment ago — only what it will be from now on.
In pure functional programming this is just made explicit. One of the simplest forms this can take is with using lists of values as records of sequential change in imperative programming. Even simpler is to use different variables altogether to represent different values of an entity at different points in time (cf. single assignment and static single assignment form, or SSA).
So instead of "changing" something that can't really be changed anyway, we make an augmented copy of it, and pass that around, using it in place of the old thing.
As a general rule, you don't (and you don't need to). However, in the interests of completeness.
import Data.IORef
main = do
i <- newIORef 0 -- new IORef i
modifyIORef i (+1) -- increase it by 1
readIORef i >>= print -- print it
However, any answer that says you need to use something like MVar, IORef, STRef etc. is wrong. There is a purely functional way to do this, which in this small rapidly written example doesn't really look very nice.
import Control.Monad.State
type Lens a b = ((a -> b -> a), (a -> b))
setL = fst
getL = snd
modifyL :: Lens a b -> a -> (b -> b) -> a
modifyL lens x f = setL lens x (f (getL lens x))
lensComp :: Lens b c -> Lens a b -> Lens a c
lensComp (set1, get1) (set2, get2) = -- Compose two lenses
(\s x -> set2 s (set1 (get2 s) x) -- Not needed here
, get1 . get2) -- But added for completeness
(+=) :: (Num b) => Lens a b -> Lens a b -> State a ()
x += y = do
s <- get
put (modifyL x s (+ (getL y s)))
swap :: Lens a b -> Lens a b -> State a ()
swap x y = do
s <- get
let x' = getL x s
let y' = getL y s
put (setL y (setL x s y') x')
nFibs :: Int -> Int
nFibs n = evalState (nFibs_ n) (0,1)
nFibs_ :: Int -> State (Int,Int) Int
nFibs_ 0 = fmap snd get -- The second Int is our result
nFibs_ n = do
x += y -- Add y to x
swap x y -- Swap them
nFibs_ (n-1) -- Repeat
where x = ((\(x,y) x' -> (x', y)), fst)
y = ((\(x,y) y' -> (x, y')), snd)
There are several solutions to translate imperative i=i+1 programming to functional programming. Recursive function solution is the recommended way in functional programming, creating a state is almost never what you want to do.
After a while you will learn that you can use [1..] if you need a index for example, but it takes a lot of time and practice to think functionally instead of imperatively.
Here's a other way to do something similar as i=i+1 not identical because there aren't any destructive updates. Note that the State monad example is just for illustration, you probably want [1..] instead:
module Count where
import Control.Monad.State
count :: Int -> Int
count c = c+1
count' :: State Int Int
count' = do
c <- get
put (c+1)
return (c+1)
main :: IO ()
main = do
-- purely functional, value-modifying (state-passing) way:
print $ count . count . count . count . count . count $ 0
-- purely functional, State Monad way
print $ (`evalState` 0) $ do {
count' ; count' ; count' ; count' ; count' ; count' }
Note: This is not an ideal answer but hey, sometimes it might be a little good to give anything at all.
A simple function to increase the variable would suffice.
For example:
incVal :: Integer -> Integer
incVal x = x + 1
main::IO()
main = do
let i = 1
print (incVal i)
Or even an anonymous function to do it.

list monad transformer

I need to use a list monad transformer. I've read that there are potential problems with ListT IO from Control.Monad.List, since IO isn't commutative, so I'm looking at ListT done right. But I'm getting some unexpected behavior.
Consider this simple test:
test = runListT $ do
x <- liftList [1..3]
liftIO $ print x
y <- liftList [6..8]
liftIO $ print (x,y)
Using Control.Monad.List:
Main> test
1
(1,6)
(1,7)
(1,8)
2
(2,6)
(2,7)
(2,8)
3
(3,6)
(3,7)
(3,8)
[(),(),(),(),(),(),(),(),()]
Using "ListT done right":
Main> test
1
(1,6)
Is this a problem with "ListT done right", or am I just using it wrong? Is there a preferred alternative?
Thanks!
This might be intensional on the part of the author, since they say
it lets each element of the list have its own side effects, which only get
`excecuted' if this element of the list is really inspected.
I'm not sure, though. Anyway, you can use this function to sequence the whole
list:
runAll_ :: (Monad m) => ListT m a -> m ()
runAll_ (ListT m) = runAll_' m where
runAll_' m = do
mm <- m
case mm of
MNil -> return ()
_ `MCons` mxs -> runAll_' mxs
And an analogous runAll that returns a list should be easy to construct.
main = runAll_ $ do
x <- liftList [1..3]
liftIO $ print x
y <- liftList [6..8]
liftIO $ print (x,y)
1
(1,6)
(1,7)
(1,8)
2
(2,6)
(2,7)
(2,8)
3
(3,6)
(3,7)
(3,8)

What is the difference between forM and forM_ in haskell?

HLint suggests that I use forM_ rather than forM. Why? I see they have different type signatures but haven't found a good reason to use one over the other.
forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b)
forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m ()
The forM_ function is more efficient because it does not save the results of the operations. That is all. (This only makes sense when working with monads because a pure function of type a -> () is not particularly useful.)
Ok,
forM is mapM with its arguments flipped.
forM_ is mapM_ with its arguments flipped.
Let's see in mapM and mapM_ :
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM mf xs takes a monadic function mf (having type Monad m => (a -> m b)) and applies it to each element in list xs; the result is a list inside a monad.
The difference between mapM and mapM_ is, that mapM returns a list of the results, while mapM_ returns an empty result. The result of each action in mapM_ is not stored.
To understand the difference between (A): forM xs f and (B): forM_ xs f, it might help to compare the difference between the following:
-- Equivalent to (A)
do
r1 <- f x1
r2 <- f x2
...
rn <- f xn
return [r1, r2, ..., rn]
-- Equivalent to (B)
do
_ <- f x1
_ <- f x2
...
_ <- f xn
return ()
The crucial difference being that forM_ ignores the results r1, ... rn and just returns an empty result via return (). Think of the underscore as meaning "don't care" ... forM_ doesn't care about the results. forM however, does care about the results and returns them in as a list via return [r1, r2, ... rn].
Example 1
The code below asks for your name three times and prints the results of the forM.
import Control.Monad (forM, forM_)
main = do
let askName i = do
putStrLn $ "What's your name (" ++ (show i) ++ ")"
name <- getLine
return name
results <- forM [1,2,3] askName
putStrLn $ "Results = " ++ show results
An example execution with forM:
What's your name? (1)
> James
What's your name? (2)
> Susan
What's your name? (3)
> Alex
Results = ["James", "Susan", "Alex"]
But if we change the forM to a forM_, then we would have instead:
What's your name? (1)
> James
What's your name? (2)
> Susan
What's your name? (3)
> Alex
Results = ()
In your case, the linter is telling you that you're not using the return values of your forM (you don't have foo <- forM xs f, you probably have forM xs f by itself on a line) and so should use forM_ instead. This happens, for
example, when you are using a monadic action like putStrLn.
Example 2 The code below asks for your name and then says "Hello" – repeating three times.
import Control.Monad (forM, forM_)
main = do
let askThenGreet i = do
putStrLn $ "What's your name (" ++ (show i) ++ ")"
name <- getLine
putStrLn $ "Hello! " ++ name
forM [1,2,3] askThenGreet
An example execution with forM:
What's your name? (1)
> Sarah
Hello! Sarah
What's your name? (2)
> Dick
Hello! Dick
What's your name? (3)
> Peter
Hello! Peter
[(), (), ()]
The overall result of main comes from the result of the forM: [(), (), ()]. It's pretty useless and annoyingly, it appears in the console. But if we change the forM to a forM_, then we would have instead:
What's your name? (1)
> Sarah
Hello! Sarah
What's your name? (2)
> Dick
Hello! Dick
What's your name? (3)
> Peter
Hello! Peter
With that change, the overall result comes from the mapM_ and is now (). This doesn't show up in the console (a quirk of the IO monad)! Great!
Also, by using mapM_ here, it's clearer to other readers of your code – you're indirectly explaining / self-documenting that you don't care about the results [r1, ..., rn] = [(), (), ()] – and rightly so as they're useless here.

Resources