Variable scope in a higher-order lambda function - haskell

In working through a solution to the 8 Queens problem, a person used the following line of code:
sameDiag try qs = any (\(colDist,q) -> abs (try - q) == colDist) $ zip [1..] qs
try is an an item; qs is a list of the same items.
Can someone explain how colDist and q in the lambda function get bound to anything?
How did try and q used in the body of lambda function find their way into the same scope?
To the degree this is a Haskell idiom, what problem does this design approach help solve?

The function any is a higher-order function that takes 2 arguments:
the 1st argument is of type a -> Bool, i.e. a function from a to Bool
the 2nd argument is of type [a], i.e. a list of items of type a;
i.e. the 1st argument is a function that takes any element from the list passed as the 2nd argument, and returns a Bool based on that element. (well it can take any values of type a, not just the ones in that list, but it's quite obviously certain that any won't be invoking it with some arbitrary values of a but the ones from the list.)
You can then simplify thinking about the original snippet by doing a slight refactoring:
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f = (\(colDist, q) -> abs (try - q) == colDist)
which can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f (colDist, q) = abs (try - q) == colDist)
which in turn can be transformed into
sameDiag :: Int -> [Int] -> Bool
sameDiag try qs = any f xs
where
xs = zip [1..] qs
f pair = abs (try - q) == colDist) where (colDist, q) = pair
(Note that sameDiag could also have a more general type Integral a => a -> [a] -> Bool rather than the current monomorphic one)
— so how does the pair in f pair = ... get bound to a value? well, simple: it's just a function; whoever calls it must pass along a value for the pair argument. — when calling any with the first argument set to f, it's the invocation of the function any who's doing the calling of f, with individual elements of the list xs passed in as values of the argument pair.
and, since the contents of xs is a list of pairs, it's OK to pass an individual pair from this list to f as f expects it to be just that.
EDIT: a further explanation of any to address the asker's comment:
Is this a fair synthesis? This approach to designing a higher-order function allows the invoking code to change how f behaves AND invoke the higher-order function with a list that requires additional processing prior to being used to invoke f for every element in the list. Encapsulating the list processing (in this case with zip) seems the right thing to do, but is the intent of this additional processing really clear in the original one-liner above?
There's really no additional processing done by any prior to invoking f. There is just very minimalistic bookkeeping in addition to simply iterating through the passed in list xs: invoking f on the elements during the iteration, and immediately breaking the iteration and returning True the first time f returns True for any list element.
Most of the behavior of any is "implicit" though in that it's taken care of by Haskell's lazy evaluation, basic language semantics as well as existing functions, which any is composed of (well at least my version of it below, any' — I haven't taken a look at the built-in Prelude version of any yet but I'm sure it's not much different; just probably more heavily optimised).
In fact, any is simple it's almost trivial to re-implement it with a one liner on a GHCi prompt:
Prelude> let any' f xs = or (map f xs)
let's see now what GHC computes as its type:
Prelude> :t any'
any' :: (a -> Bool) -> [a] -> Bool
— same as the built-in any. So let's give it some trial runs:
Prelude> any' odd [1, 2, 3] -- any odd values in the list?
True
Prelude> any' even [1, 3] -- any even ones?
False
Prelude> let adult = (>=18)
Prelude> any' adult [17, 17, 16, 15, 17, 18]
— see how you can sometimes write code that almost looks like English with higher-order functions?

zip :: [a] -> [b] -> [(a,b)] takes two lists and joins them into pairs, dropping any remaining at the end.
any :: (a -> Bool) -> [a] -> Bool takes a function and a list of as and then returns True if any of the values returned true or not.
So colDist and q are the first and second elements of the pairs in the list made by zip [1..] qs, and they are bound when they are applied to the pair by any.
q is only bound within the body of the lambda function - this is the same as with lambda calculus. Since try was bound before in the function definition, it is still available in this inner scope. If you think of lambda calculus, the term \x.\y.x+y makes sense, despite the x and the y being bound at different times.
As for the design approach, this approach is much cleaner than trying to iterate or recurse through the list manually. It seems quite clear in its intentions to me (with respect to the larger codebase it comes from).

Related

Haskell recursive function example with foldr

I've taken up learning Haskell again, after a short hiatus and I am currently trying to get a better understanding of how recursion and lambda expressions work in Haskell.
In this: YouTube video, there is a function example that puzzles me far more than it probably should, in terms of how it actually works:
firstThat :: (a -> Bool) -> a -> [a] -> a
firstThat f = foldr (\x acc -> if f x then x else acc)
For the sake of clarity and since it wasn't immediately obvious to me, I'll give an example of applying this function to some arguments:
firstThat (>10) 2000 [10,20,30,40] --returns 20, but would return 2000, if none of the values in the list were greater than 10
Please correct me, if my assumptions are wrong.
It seems firstThat takes three arguments:
a function that takes one arguments and returns a Boolean value. Since the > operator is actually an infix function, the first argument in the example above seems the result of a partial application to the > function – is this correct?
an unspecified value of the same type expected as the missing argument to the function provided as the first argument
a list of values of the aforementioned type
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening. The lambda expression provided as an argument to foldr seem to be missing its arguments too.
So, how exactly does this function work? I apologize if I am being too dense or fail to see the forest for the trees, but I just cannot wrap my head around it, which is frustrating.
Any helpful explanation or example(s) would be greatly appreciated.
Thanks!
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening.
You are right. However, there is a nicer way of putting it than talking about "missing arguments" -- one that doesn't lead you into asking where they have gone. Here are two ways in which the arguments are not missing.
Firstly, consider this function:
add :: Num a => a -> a -> a
add x y = x + y
As you may know, we can also define it like this:
add :: Num a => a -> a -> a
add = (+)
That works because Haskell functions are values like any other. We can simply define a value, add, as being equal to another value, (+), which just happens to be a function. There is no special syntax required to declare a function. The upshot is that writing arguments explicitly is (almost) never necessary; the main reason why we do so because it often makes code more readable (for instance, I could define firstThat without writing the f parameter explicitly, but I won't do so because the result is rather hideous).
Secondly, whenever you see a function type with three arguments...
firstThat :: (a -> Bool) -> a -> [a] -> a
... you can also read it like this...
firstThat :: (a -> Bool) -> (a -> [a] -> a)
... that is, a function of one argument that produces a function of two arguments. That works for all functions of more than one argument. The key takeaway is that, at heart, all Haskell functions take just one argument. That is why partial application works. So on seeing...
firstThat :: (a -> Bool) -> a -> [a] -> a
firstThat f = foldr (\x acc -> if f x then x else acc)
... you can accurately say that you have written explicitly all parameters that firstThat takes -- that is, only one :)
The lambda expression provided as an argument to foldr seem to be missing its arguments too.
Not really. foldr (when restricted to lists) is...
foldr :: (a -> b -> b) -> b -> [a] -> b
... and so the function passed to it takes two arguments (feel free to add air quotes around "two", given the discussion above). The lambda was written as...
\x acc -> if f x then x else acc
... with two explicit arguments, x and acc.
a function that takes one arguments and returns a Boolean value. Since the > operator is actually an infix function, the first argument in the example above seems the result of a partial application to the > function – is this correct?
yes: (>10) is short for \x -> x > 10, just as (10>) would be short for \x -> 10 > x.
an unspecified value of the same type expected as the missing argument to the function provided as the first argument
first of all, it's not a missing argument: by omitting an argument, you obtain a function value. however, the type of the 2nd argument does indeed match the argument of the function >10, just as it matches the type of the elements of the list [10,20,30,40] (which is better reasoning).
a list of values of the aforementioned type
yes.
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening. The lambda expression provided as an argument to foldr seem to be missing its arguments too.
that's because given e.g. foo x y z = x * y * z, these 2 lines are equivalent:
bar x = foo x
bar x y z = foo x y z
— that's because of a concept called currying. Currying is also the reason why function type signatures are not (a, b) -> c but instead a -> b -> c, which in turn is equivalent to a -> (b -> c) because of the right associativity of the -> type operator.
Therefore, these two lines are equivalent:
firstThat f = foldr (\x acc -> if f x then x else acc)
firstThat f x y = foldr (\x acc -> if f x then x else acc) x y
Note: that you can also use Data.List.find combined with Data.Maybe.fromMaybe:
λ> fromMaybe 2000 $ find (>10) [10, 20, 30]
20
λ> fromMaybe 2000 $ find (>10) [1, 2, 3]
2000
See also:
https://en.wikipedia.org/wiki/Currying.
https://www.fpcomplete.com/user/EFulmer/currying-and-partial-application
http://learnyouahaskell.com/higher-order-functions

Would the ability to detect cyclic lists in Haskell break any properties of the language?

In Haskell, some lists are cyclic:
ones = 1 : ones
Others are not:
nums = [1..]
And then there are things like this:
more_ones = f 1 where f x = x : f x
This denotes the same value as ones, and certainly that value is a repeating sequence. But whether it's represented in memory as a cyclic data structure is doubtful. (An implementation could do so, but this answer explains that "it's unlikely that this will happen in practice".)
Suppose we take a Haskell implementation and hack into it a built-in function isCycle :: [a] -> Bool that examines the structure of the in-memory representation of the argument. It returns True if the list is physically cyclic and False if the argument is of finite length. Otherwise, it will fail to terminate. (I imagine "hacking it in" because it's impossible to write that function in Haskell.)
Would the existence of this function break any interesting properties of the language?
Would the existence of this function break any interesting properties of the language?
Yes it would. It would break referential transparency (see also the Wikipedia article). A Haskell expression can be always replaced by its value. In other words, it depends only on the passed arguments and nothing else. If we had
isCycle :: [a] -> Bool
as you propose, expressions using it would not satisfy this property any more. They could depend on the internal memory representation of values. In consequence, other laws would be violated. For example the identity law for Functor
fmap id === id
would not hold any more: You'd be able to distinguish between ones and fmap id ones, as the latter would be acyclic. And compiler optimizations such as applying the above law would not longer preserve program properties.
However another question would be having function
isCycleIO :: [a] -> IO Bool
as IO actions are allowed to examine and change anything.
A pure solution could be to have a data type that internally distinguishes the two:
import qualified Data.Foldable as F
data SmartList a = Cyclic [a] | Acyclic [a]
instance Functor SmartList where
fmap f (Cyclic xs) = Cyclic (map f xs)
fmap f (Acyclic xs) = Acyclic (map f xs)
instance F.Foldable SmartList where
foldr f z (Acyclic xs) = F.foldr f z xs
foldr f _ (Cyclic xs) = let r = F.foldr f r xs in r
Of course it wouldn't be able to recognize if a generic list is cyclic or not, but for many operations it'd be possible to preserve the knowledge of having Cyclic values.
In the general case, no you can't identify a cyclic list. However if the list is being generated by an unfold operation then you can. Data.List contains this:
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
The first argument is a function that takes a "state" argument of type "b" and may return an element of the list and a new state. The second argument is the initial state. "Nothing" means the list ends.
If the state ever recurs then the list will repeat from the point of the last state. So if we instead use a different unfold function that returns a list of (a, b) pairs we can inspect the state corresponding to each element. If the same state is seen twice then the list is cyclic. Of course this assumes that the state is an instance of Eq or something.

How to implement delete with foldr in Haskell

I've been studying folds for the past few days. I can implement simple functions with them, like length, concat and filter. What I'm stuck at is trying to implement with foldr functions like delete, take and find. I have implemented these with explicit recursion but it doesn't seem obvious to me how to convert these types of functions to right folds.
I have studied the tutorials by Graham Hutton and Bernie Pope. Imitating Hutton's dropWhile, I was able to implement delete with foldr but it fails on infinite lists.
From reading Implement insert in haskell with foldr, How can this function be written using foldr? and Implementing take using foldr, it would seem that I need to use foldr to generate a function which then does something. But I don't really understand these solutions and don't have an idea how to implement for example delete this way.
Could you explain to me a general strategy for implementing with foldr lazy versions of functions like the ones I mentioned. Maybe you could also implement delete as an example since this probably is one of the easiest.
I'm looking for a detailed explanation that a beginner can understand. I'm not interested in just solutions, I want to develop an understanding so I can come up with solutions to similar problems myself.
Thanks.
Edit: At the moment of writing there is one useful answer but it's not quite what I was looking for. I'm more interested in an approach that uses foldr to generate a function, which then does something. The links in my question have examples of this. I don't quite understand those solutions so I would like to have more information on this approach.
delete is a modal search. It has two different modes of operation - whether it's already found the result or not. You can use foldr to construct a function that passes the state down the line as each element is checked. So in the case of delete, the state can be a simple Bool. It's not exactly the best type, but it will do.
Once you have identified the state type, you can start working on the foldr construction. I'm going to walk through figuring it out the way I did. I'll be enabling ScopedTypeVariables just so I can annotate the type of subexpressions better. One you know the state type, you know you want foldr to generate a function taking a value of that type, and returning a value of the desired final type. That's enough to start sketching things.
{-# LANGUAGE ScopedTypeVariables #-}
delete :: forall a. Eq a => a -> [a] -> [a]
delete a xs = foldr f undefined xs undefined
where
f :: a -> (Bool -> [a]) -> (Bool -> [a])
f x g = undefined
It's a start. The exact meaning of g is a little bit tricky here. It's actually the function for processing the rest of the list. It's accurate to look at it as a continuation, in fact. It absolutely represents performing the rest of the folding, with your whatever state you choose to pass along. Given that, it's time to figure out what to put in some of those undefined places.
{-# LANGUAGE ScopedTypeVariables #-}
delete :: forall a. Eq a => a -> [a] -> [a]
delete a xs = foldr f undefined xs undefined
where
f :: a -> (Bool -> [a]) -> (Bool -> [a])
f x g found | x == a && not found = g True
| otherwise = x : g found
That seems relatively straightforward. If the current element is the one being searched for, and it hasn't yet been found, don't output it, and continue with the state set to True, indicating it's been found. otherwise, output the current value and continue with the current state. This just leaves the rest of the arguments to foldr. The last one is the initial state. The other one is the state function for an empty list. Ok, those aren't too bad either.
{-# LANGUAGE ScopedTypeVariables #-}
delete :: forall a. Eq a => a -> [a] -> [a]
delete a xs = foldr f (const []) xs False
where
f :: a -> (Bool -> [a]) -> (Bool -> [a])
f x g found | x == a && not found = g True
| otherwise = x : g found
No matter what the state is, produce an empty list when an empty list is encountered. And the initial state is that the element being searched for has not yet been found.
This technique is also applicable in other cases. For instance, foldl can be written as a foldr this way. If you look at foldl as a function that repeatedly transforms an initial accumulator, you can guess that's the function being produced - how to transform the initial value.
{-# LANGUAGE ScopedTypeVariables #-}
foldl :: forall a b. (a -> b -> a) -> a -> [b] -> a
foldl f z xs = foldr g id xs z
where
g :: b -> (a -> a) -> (a -> a)
g x cont acc = undefined
The base cases aren't too tricky to find when the problem is defined as manipulating the initial accumulator, named z there. The empty list is the identity transformation, id, and the value passed to the created function is z.
The implementation of g is trickier. It can't just be done blindly on types, because there are two different implementations that use all the expected values and type-check. This is a case where types aren't enough, and you need to consider the meanings of the functions available.
Let's start with an inventory of the values that seem like they should be used, and their types. The things that seem like they must need to be used in the body of g are f :: a -> b -> a, x :: b, cont :: (a -> a), and acc :: a. f will obviously take x as its second argument, but there's a question of the appropriate place to use cont. To figure out where it goes, remember that it represents the transformation function returned by processing the rest of the list, and that foldl processes the current element and then passes the result of that processing to the rest of the list.
{-# LANGUAGE ScopedTypeVariables #-}
foldl :: forall a b. (a -> b -> a) -> a -> [b] -> a
foldl f z xs = foldr g id xs z
where
g :: b -> (a -> a) -> (a -> a)
g x cont acc = cont $ f acc x
This also suggests that foldl' can be written this way with only one tiny change:
{-# LANGUAGE ScopedTypeVariables #-}
foldl' :: forall a b. (a -> b -> a) -> a -> [b] -> a
foldl' f z xs = foldr g id xs z
where
g :: b -> (a -> a) -> (a -> a)
g x cont acc = cont $! f acc x
The difference is that ($!) is used to suggest evaluation of f acc x before it's passed to cont. (I say "suggest" because there are some edge cases where ($!) doesn't force evaluation even as far as WHNF.)
delete doesn't operate on the entire list evenly. The structure of the computation isn't just considering the whole list one element at a time. It differs after it hits the element it's looking for. This tells you it can't be implemented as just a foldr. There will have to be some sort of post-processing involved.
When that happens, the general pattern is that you build a pair of values and just take one of them at completion of the foldr. That's probably what you did when you imitated Hutton's dropWhile, though I'm not sure since you didn't include code. Something like this?
delete :: Eq a => a -> [a] -> [a]
delete a = snd . foldr (\x (xs1, xs2) -> if x == a then (x:xs1, xs1) else (x:xs1, x:xs2)) ([], [])
The main idea is that xs1 is always going to be the full tail of the list, and xs2 is the result of the delete over the tail of the list. Since you only want to remove the first element that matches, you don't want to use the result of delete over the tail when you do match the value you're searching for, you just want to return the rest of the list unchanged - which fortunately is what's always going to be in xs1.
And yeah, that doesn't work on infinite lists - but only for one very specific reason. The lambda is too strict. foldr only works on infinite lists when the function it is provided doesn't always force evaluation of its second argument, and that lambda does always force evaluation of its second argument in the pattern match on the pair. Switching to an irrefutable pattern match fixes that, by allowing the lambda to produce a constructor before ever examining its second argument.
delete :: Eq a => a -> [a] -> [a]
delete a = snd . foldr (\x ~(xs1, xs2) -> if x == a then (x:xs1, xs1) else (x:xs1, x:xs2)) ([], [])
That's not the only way to get that result. Using a let-binding or fst and snd as accessors on the tuple would also do the job. But it is the change with the smallest diff.
The most important takeaway here is to be very careful with handling the second argument to the reducing function you pass to foldr. You want to defer examining the second argument whenever possible, so that the foldr can stream lazily in as many cases as possible.
If you look at that lambda, you see that the branch taken is chosen before doing anything with the second argument to the reducing function. Furthermore, you'll see that most of the time, the reducing function produces a list constructor in both halves of the result tuple before it ever needs to evaluate the second argument. Since those list constructors are what make it out of delete, they are what matter for streaming - so long as you don't let the pair get in the way. And making the pattern-match on the pair irrefutable is what keeps it out of the way.
As a bonus example of the streaming properties of foldr, consider my favorite example:
dropWhileEnd :: (a -> Bool) -> [a] -> [a]
dropWhileEnd p = foldr (\x xs -> if p x && null xs then [] else x:xs) []
It streams - as much as it can. If you figure out exactly when and why it does and doesn't stream, you'll understand pretty much every detail of the streaming structure of foldr.
here is a simple delete, implemented with foldr:
delete :: (Eq a) => a -> [a] -> [a]
delete a xs = foldr (\x xs -> if x == a then (xs) else (x:xs)) [] xs

Referring to previous term in a list in Haskell

There's something I'd like to be able to do in Haskell, but it's not obvious if it's possible. I'm a novice (for instance, I don't yet understand monads), so maybe there is some advanced way of doing it.
Suppose I have defined a function f from some type to itself. I would like to be able to define a notion "prev" that would stand for the previous element in a list (of elements of the given type). So I would like something like [x, y, f prev] to mean [x, y, f y]. I don't mind if the definition involves zipping the list with the natural numbers, as long as what I get to write in the end can hide the method of construction.
One reason this may be impossible is that if it is possible, then one ought also to be able to define a notion of "next", and one wouldn't want to be able to write [f next, g prev]. If it is impossible, is there a next best option?
I don't think there's a way to introduce a new keyword prev to get the exact syntax you describe, at least short of some techniques that would be significant overkill for this scenario, like implicit parameters or Template Haskell.
However you can do this using a technique called tying the recursive knot:
type PrevList a = [a -> a]
instantiatePrevList :: PrevList a -> [a]
instantiatePrevList prevList =
let result =
zipWith (\f prev -> f prev)
prevList
(error "Initial element has no previous element":result)
in result
xs = instantiatePrevList [\_ -> 5, \_ -> 3, \prev -> prev + 1]
The idea is to define your list in terms of functions that are always passed the previous value - the PrevList type above. You can then choose to ignore it if you don't need it for a particular element.
We then need a function to put it all together which is what instantiatePrevList does.
Notice that the list result is defined in terms of itself, which is where the "tying the knot" comes in - it relies on Haskell's laziness to work.
The other way laziness is used is for the first element, which has no previous. As long as you don't try to use the previous value in the first element of your list, the error won't be hit.
As you surmise, the same technique could also be used to define a next - and it would still work fine as long as you don't write something that is actually dependent on itself in a non-terminating way.
EDIT:
Actually a solution with implicit parameters isn't too complicated and it does make for nicer syntax writing the lists:
{-# LANGUAGE ImplicitParams, ImpredicativeTypes, ScopedTypeVariables #-}
type PrevList a = [(?prev :: a) => a]
instantiatePrevList :: PrevList a -> [a]
instantiatePrevList prevList =
let result =
zipWith (\(elem :: ((?prev :: a) => a)) prev ->
let ?prev = prev in elem)
prevList
(error "Initial element has no previous element":result)
in result
xs = instantiatePrevList [5, 3, ?prev + 1]
You do have to be a bit careful with them though, you might get confusing results if you try to nest them - e.g. by having a PrevList within another PrevList.
You can define your own knot-tying combinators to obtain something like
example :: [Int]
example = tie [ const 1, succ . prev, succ . prev, (*2) . next, const 100, const 20 ]
-- yields [ 1, 2, 3, 200, 100, 20 ]
Intuitively, const value means that value is the element of the list. Instead,
operation . prev means that this element is obtained applying operation to the previous
element. The expression operation . next works similarly.
Further, you can refer to both previous and next using uncurry e..g.
example2 :: [Int]
example2 = tie [ const 100, uncurry (+), const 5 ]
-- yields [ 100, 105, 5 ]
A possible implementation is
tie :: [ (a,a) -> a ] -> [a]
tie = go (error "no previous element")
where go _ [] = []
go pr (f:fs) = this : rest
where rest = go this fs
this = f (pr, head rest)
prev :: (a,a) -> a
prev = fst
next :: (a,a) -> a
next = snd
Live demo

Define a haskell function [IO a] -> IO[a]

I am doing a haskell exercise, regarding define a function accumulate :: [IO a] -> IO [a]
which performs a sequence of interactions and accumulates their result in a list.
What makes me confused is how to express a list of IO a ? (action:actions)??
how to write recursive codes using IO??
This is my code, but these exists some problem...
accumulate :: [IO a] -> IO [a]
accumulate (action:actions) = do
value <- action
list <- accumulate (action:actions)
return (convert_to_list value list)
convert_to_list:: Num a =>a -> [a]-> [a]
convert_to_list a [] = a:[]
convert_to_list x xs = x:xs
What you are trying to implement is sequence from Control.Monad.
Just to let you find the answer instead of giving it, try searching for [IO a] -> IO [a] on hoogle (there's a Source link on the right hand side of the page when you've chosen a function).
Try to see in your code what happens when list of actions is empty list and see what does sequence do to take care of that.
There is already such function in Control.Monad and it called sequence (no you shouldn't look at it). You should denote the important decision taken during naming of it. Technically [IO a] says nothing about in which order those Monads should be attached to each other, but name sequence puts a meaning of sequential attaching.
As for the solving you problem. I'd suggest to look more at types and took advice of #sacundim. In GHCi (interpreter from Glasgow Haskell Compiler) there is pretty nice way to check type and thus understand expression (:t (:) will return (:) :: a -> [a] -> [a] which should remind you one of you own function but with less restrictive types).
First of all I'd try to see at what you have showed with more simple example.
data MyWrap a = MyWrap a
accumulate :: [MyWrap a] -> MyWrap [a]
accumulate (action:actions) = MyWrap (convert_to_list value values) where
MyWrap value = action -- use the pattern matching to unwrap value from action
-- other variant is:
-- value = case action of
-- MyWrap x -> x
MyWrap values = accumulate (action:actions)
I've made the same mistake that you did on purpose but with small difference (values is a hint). As you probably already have been told you could try to interpret any of you program by trying to inline appropriate functions definitions. I.e. match definitions on the left side of equality sign (=) and replace it with its right side. In your case you have infinite cycle. Try to solve it on this sample or your and I think you'll understand (btw your problem might be just a typo).
Update: Don't be scary when your program will fall in runtime with message about pattern match. Just think of case when you call your function as accumulate []
Possibly you looking for sequence function that maps [m a] -> m [a]?
So the short version of the answer to your question is, there's (almost) nothing wrong with your code.
First of all, it typechecks:
Prelude> let accumulate (action:actions) = do { value <- action ;
list <- accumulate (action:actions) ; return (value:list) }
Prelude> :t accumulate
accumulate :: (Monad m) => [m t] -> m [t]
Why did I use return (value:list) there? Look at your second function, it's just (:). Calling g
g a [] = a:[]
g a xs = a:xs
is the same as calling (:) with the same arguments. This is what's known as "eta reduction": (\x-> g x) === g (read === as "is equivalent").
So now just one problem remains with your code. You've already taken a value value <- action out of the action, so why do you reuse that action in list <- accumulate (action:actions)? Do you really have to? Right now you have, e.g.,
accumulate [a,b,c] ===
do { v1<-a; ls<-accumulate [a,b,c]; return (v1:ls) } ===
do { v1<-a; v2<-a; ls<-accumulate [a,b,c]; return (v1:v2:ls) } ===
do { v1<-a; v2<-a; v3<-a; ls<-accumulate [a,b,c]; return (v1:v2:v3:ls) } ===
.....
One simple fix and you're there.

Resources