How can I solve this following function in haskell? - haskell

I've Seen this following exercise in a book and there was no sample solution for that. I'm very new to functions of higher orders and i'm not sure how should i implement this function.I thought maybe you can give me some ideas.
I should implement a function foldleft :: (a -> b -> a) -> a -> [b] -> a, by that for every is valid that:
f :: a -> b -> a and a0 :: a,b1, …, bk :: b,k∈N and foldleft f a0 [b1, …, bk] = f (f … (f a0 b1) ⋯ bk−1)bk
,
so for example:
foldleft(+) 5 [1, 4, 3] = (+) ((+) ((+) 5 1) 4) 3 = ((5 + 1) + 4) + 3
and in particular, it should apply : foldleft f a [] = a

You can do pattern matching on the two data constructors of a list: the empty list, and the "cons" (:), so:
foldleft :: (a -> b -> a) -> a -> [b] -> a
foldleft f z [] = …
foldleft f z (x:xs) = …
for the second clause you will need to apply f on a and the head of the list, and then use this as initial accumulator when recursing on the tail of the list.

Start by breaking it into two cases:
foldleft f a0 [] = ...
foldleft f a0 (b1:b2_through_bk) = ...
Then look at the equations in your specification, and see which, if any, of them can help you start filling in the ...s.

Related

Haskell dependent, independent variables in lambda function as applied to foldr

Given
> foldr (+) 5 [1,2,3,4]
15
this second version
foldr (\x n -> x + n) 5 [1,2,3,4]
also returns 15. The first thing I don't understand about the second version is how foldr knows which variable is associated with the accumulator-seed 5 and which with the list variable's elements [1,2,3,4]. In the lambda calculus way, x would seem to be the dependent variable and n the independent variable. So if this
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
is foldr and these
:type foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
:t +d foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
its type declarations, can I glean, deduce the answer to "which is dependent and which is independent" from the type declaration itself? It would seem both examples of foldr above must be doing this
(+) 1 ((+) 2 ((+) 3 ((+) 4 ((+) 5 0))))
I simply guessed the second, lambda function version above, but I don't really understand how it works, whereas the first version with (+) breaks down as shown directly above.
Another example would be this
length' = foldr (const (1+)) 0
where, again, const seems to know to "throw out" the incoming list elements and simply increment, starting with the initial accumulator value. This is the same as
length' = foldr (\_ acc -> 1 + acc) 0
where, again, Haskell knows which of foldr's second and third arguments -- accumulator and list -- to treat as the dependent and independent variable, seemingly by magic. But no, I'm sure the answer lies in the type declaration (which I can't decipher, hence, this post), as well as the lore of lambda calculus, of which I'm a beginner.
Update
I've found this
reverse = foldl (flip (:)) []
and then applying to a list
foldl (flip (:)) [] [1,2,3]
foldl (flip (:)) (1:[]) [2,3]
foldl (flip (:)) (2:1:[]) [3]
foldl (flip (:)) (3:2:1:[]) []
. . .
Here it's obvious that the order is "accumulator" and then list, and flip is flipping the first and second variables, then subjecting them to (:). Again, this
reverse = foldl (\acc x -> x : acc) []
foldl (\acc x -> x : acc) [] [1,2,3]
foldl (\acc x -> x : acc) (1:[]) [1,2,3]
. . .
seems also to rely on order, but in the example from further above
length' = foldr (\_ acc -> 1 + acc) 0
foldr (\_ acc -> 1 + acc) 0 [1,2,3]
how does it know 0 is the accumulator and is bound to acc and not the first (ghost) variable? So as I understand (the first five pages of) lambda calculus, any variable that is "lambda'd," e.g., \x is a dependent variable, and all other non-lambda'd variables are independent. Above, the \_ is associated with [1,2,3] and the acc, ostensibly the independent variable, is 0; hence, order is not dictating assignment. It's as if acc was some keyword that when used always binds to the accumulator, while x is always talking about the incoming list members.
Also, what is the "algebra" in the type definition where t a is transformed to [a]? Is this something from category theory? I see
Data.Foldable.toList :: t a -> [a]
in the Foldable definition. Is that all it is?
By "dependent" you most probably mean bound variable.
By "independent" you most probably mean free (i.e. not bound) variable.
There are no free variables in (\x n -> x + n). Both x and n appear to the left of the arrow, ->, so they are named parameters of this lambda function, bound inside its body, to the right of the arrow. Being bound means that each reference to n, say, in the function's body is replaced with the reference to the corresponding argument when this lambda function is indeed applied to its argument(s).
Similarly both _ and acc are bound in (\_ acc -> 1 + acc)'s body. The fact that the wildcard is used here, is immaterial. We could just have written _we_dont_care_ all the same.
The parameters in lambda function definition get "assigned" (also called "bound") the values of the arguments in an application, purely positionally. The first argument will be bound / assigned to the first parameter, the second argument - to the second parameter. Then the lambda function's body will be entered and further reduced according to the rules.
This can be seen a bit differently stating that actually in lambda calculus all functions have only one parameter, and multi-parameter functions are actually nested uni-parameter lambda functions; and that the application is left-associative i.e. nested to the left.
What this actually means is quite simply
(\ x n -> x + n) 5 0
=
(\ x -> (\ n -> x + n)) 5 0
=
((\ x -> (\ n -> x + n)) 5) 0
=
(\ n -> 5 + n) 0
=
5 + 0
As to how Haskell knows which is which from the type signatures, again, the type variables in the functional types are also positional, with first type variable corresponding to the type of the first expected argument, the second type variable to the second expected argument's type, and so on.
It is all purely positional.
Thus, as a matter of purely mechanical and careful substitution, since by the definition of foldr it holds that foldr g 0 [1,2,3] = g 1 (foldr g 0 [2,3]) = ... = g 1 (g 2 (g 3 0)), we have
foldr (\x n -> x + n) 0 [1,2,3]
=
(\x n -> x + n) 1 ( (\x n -> x + n) 2 ( (\x n -> x + n) 3 0 ))
=
(\x -> (\n -> x + n)) 1 ( (\x n -> x + n) 2 ( (\x n -> x + n) 3 0 ))
=
(\n -> 1 + n) ( (\x n -> x + n) 2 ( (\x n -> x + n) 3 0 ))
=
1 + ( (\x n -> x + n) 2 ( (\x n -> x + n) 3 0 ))
=
1 + ( (\x (\n -> x + n)) 2 ( (\x n -> x + n) 3 0 ))
=
1 + (\n -> 2 + n) ( (\x n -> x + n) 3 0 )
=
1 + (2 + (\x n -> x + n) 3 0 )
=
1 + (2 + (\x -> (\n -> x + n)) 3 0 )
=
1 + (2 + (\n -> 3 + n) 0 )
=
1 + (2 + ( 3 + 0))
In other words, there is absolutely no difference between (\x n -> x + n) and (+).
As for that t in foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b, what that means is that given a certain type T a, if instance Foldable T exists, then the type becomes foldr :: (a -> b -> b) -> b -> T a -> b, when it's used with a value of type T a.
One example is Maybe a and thus foldr (g :: a -> b -> b) (z :: b) :: Maybe a -> b.
Another example is [] a and thus foldr (g :: a -> b -> b) (z :: b) :: [a] -> b.
(edit:) So let's focus on lists. What does it mean for a function foo to have that type,
foo :: (a -> b -> b) -> b -> [a] -> b
? It means that it expects an argument of type a -> b -> b, i.e. a function, let's call it g, so that
foo :: (a -> b -> b) -> b -> [a] -> b
g :: a -> b -> b
-------------------------------------
foo g :: b -> [a] -> b
which is itself a function, expecting of some argument z of type b, so that
foo :: (a -> b -> b) -> b -> [a] -> b
g :: a -> b -> b
z :: b
-------------------------------------
foo g z :: [a] -> b
which is itself a function, expecting of some argument xs of type [a], so that
foo :: (a -> b -> b) -> b -> [a] -> b
g :: a -> b -> b
z :: b
xs :: [a]
-------------------------------------
foo g z xs :: b
And what could such function foo g z do, given a list, say, [x] (i.e. x :: a, [x] :: [a])?
foo g z [x] = b where
We need to produce a b value, but how? Well, g :: a -> b -> b produces a function b -> b given an value of type a. Wait, we have that!
f = g x -- f :: b -> b
and what does it help us? Well, we have z :: b, so
b = f z
And what if it's [] we're given? We don't have any as then at all, but we have a b type value, z -- so instead of the above we'd just define
b = z
And what if it's [x,y] we're given? We'll do the same f-building trick, twice:
f1 = g x -- f1 :: b -> b
f2 = g y -- f2 :: b -> b
and to produce b we have many options now: it's z! or maybe, it's f1 z!? or f2 z? But the most general thing we can do, making use of all the data we have access to, is
b = f1 (f2 z)
for a right-fold (...... or,
b = f2 (f1 z)
for a left).
And if we substitute and simplify, we get
foldr g z [] = z
foldr g z [x] = g x z -- = g x (foldr g z [])
foldr g z [x,y] = g x (g y z) -- = g x (foldr g z [y])
foldr g z [x,y,w] = g x (g y (g w z)) -- = g x (foldr g z [y,w])
A pattern emerges.
Etc., etc., etc.
A sidenote: b is a bad naming choice, as is usual in Haskell. r would be much much better -- a mnemonic for "recursive result".
Another mnemonic is the order of g's arguments: a -> r -> r suggests, nay dictates, that a list's element a comes as a first argument; r the recursive result comes second (the Result of Recursively processing the Rest of the input list -- recursively, thus in the same manner); and the overall result is then produced by this "step"-function, g.
And that's the essence of recursion: recursively process self-similar sub-part(s) of the input structure, and complete the processing by a simple single step:
a a
: `g`
[a] r
------------- -------------
[a] r
[a]
a [a]
--------
(x : xs) -> r
xs -> r
----------------------
( x , r ) -> r --- or, equivalently, x -> r -> r
Well, the foldr itself knows this by definition. It was defined in such way that its function argument accepts the accumulator as 2nd argument.
Just like when you write a div x y = ... function you are free to use y as dividend.
Maybe you got confused by the fact that foldr and foldl has swapped arguments in the accumulator funtions?
As Steven Leiva says here, a foldr (1) takes a list and replaces the cons operators (:) with the given function and (2) replaces the last empty list [] with the accumulator-seed, which is what the definition of foldr says it will do
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
So de-sugared [1,2,3] is
(:) 1 ((:) 2 ((:) 3 []))
and the recursion is in effect replacing the (:) with f, and as we see in foldr f z (x:xs) = f x (foldr f z xs), the z seed value is going along for the ride until the base case where it is substituted for the [], fulfilling (1) and (2) above.
My first confusion was seeing this
foldr (\x n -> x + n) 0 [1,2,3]
and not understanding it would be expanded out, per definition above, to
(\x n -> x + n) 1 ((\x n -> x + n) 2 ((\x n -> x + n) 3 0 ))
Next, due to a weak understanding of how the actual beta reduction would progress, I didn't understand the second-to-third step below
(\x -> (\n -> x + n)) 1 ...
(\n -> 1 + n) ...
1 + ...
That second-to-third step is lambda calculus being bizarre all right, but is at the root of why (+) and (\x n -> x + n) are the same thing. I don't think it's pure lambda calculus addition, but it (verbosely) mimics addition in recursion. I probably need to jump back into lambda calculus to really grasp why (\n -> 1 + n) turns into 1 +
My worse mental block was thinking I was looking at some sort of eager evaluation inside the parentheses first
foldr ((\x n -> x + n) 0 [1,2,3,4])
where the three arguments to foldr would interact first, i.e., 0 would be bound to the x and the list member to the n
(\x n -> x + n) 0 [1,2,3,4]
0 + 1
. . . then I didn't know what to think. Totally wrong-headed, even though, as Will Ness points out above, beta reduction is positional in binding arguments to variables. But, of course, I left out the fact that Haskell currying means we follow the expansion of foldr first.
I still don't fully understand the type definition
foldr :: (a -> b -> b) -> b -> [a] -> b
other than to comment/guess that the first a and the [a] mean a is of the type of the members of the incoming list and that the (a -> b -> b) is a prelim-microcosm of what foldr will do, i.e., it will take an argument of the incoming list's type (in our case the elements of the list?) then another object of type b and produce an object b. So the seed argument is of type b and the whole process will finally produce something of type b, also the given function argument will take an a and ultimately give back an object b which actually might be of type a as well, and in fact is in the above example with integers... IOW, I don't really have a firm grasp of the type definition...

Haskell - Check if position is even/odd

What I need to do is to apply alternately 2 functions in a list. For example:
(*2) (-3) [4,5,6,7,8]
would result in
[8,2,12,4,16], because 4*2, 5-3, 6*2, 7-3, 8*2...
What I was thinking was
funct :: (a -> b) -> (a -> b) -> [a] -> [b]
and then something like
[f x | x <- xs] however I won't have just "f", but will have the other function as well.
So I was thinking about checking the position of x. If it is an even position, then f x. Otherwise g x.
Could someone help me?
Tks.
You do not really need the index, what you need is a list that alternates between (*2) and (-3). We can make use of cycle :: [a] -> [a] and zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]. We can thus use:
zipWith ($) (cycle [(2*), subtract 3]) [4,5,6,7,8]
Here ($) :: (a -> b) -> a -> b is used to perform a function application. So ($) f x is equivalent to f x.
This gives the expected:
Prelude> zipWith ($) (cycle [(2*), subtract 3]) [4,5,6,7,8]
[8,2,12,4,16]
You could always write this out with explicit recursion, to be completely clear about how it works:
alternateFunctions _ _ [] = []
alternateFunctions f g (x:xs) = f x:alternateFunctions g f xs
For an empty list, there's nothing to do. Otherwise, apply the first function to the first element, and recurse for the rest of the list with the first and second functions switched. With that, you have alternateFunctions (*2) (subtract 3) [4,5,6,7,8] = [8,2,12,4,16], as desired.
If you care about performance, then you should rewrite this as a foldr, so that it can fuse:
alternateFunctions f g xs = foldr go mempty xs f g
where go x acc f g = f x:acc g f

Partition list based on data constructor

Let's say I have the following:
data D = A Int | B Int deriving Show
and I have a function
simplify :: [D] -> [D]
My goal is for simplify to create a new list where it will add up all values with data A (into a single value of data A) and keep the B data as is.
As an example, [A 1, A 2, A 3, B 1, A 4, B 2] would become [A 10, B 1, B 2].
I know I can do it with foldl:
A (foldl (+) 0 [x | A x <- ll]) : [B x | B x <- ll]
But this involves going through the list twice looking for constructors.
I was wondering if there was a way of using partition, where I could separate the list into those that have data A and those that do not.
This seems doable if you're okay with always having the A value ahead of the Bs.
simplify :: [D] -> [D]
simplify = uncurry (:) . foldr f (A 0, [])
where
f (A x) ((A n), acc) = (A (n+x), acc)
f b (a , acc) = (a , b:acc)
Though honestly I think the uncurry (:) is a mistake here, and your final type should be:
simplify :: [D] -> (D, [D])
You don't need partition for that, just a left fold:
import Data.List (mapAccumL)
simplify :: [D] -> [D]
simplify = f . mapAccumL g 0
where
g acc (A i) = acc `seq` (acc+i, [])
g acc b = (acc, [b])
f (acc, ys) = A acc : concat ys

Haskell- function that accepts a list of functions

I need to write a function that accepts a list of functions, and a value, as parameters. Every function in the list must be applied, in turn, on the value.
For example, if my function is called compFuncs...
compFuncs [f,g,h] val equivalent to f(g(h val))
I can already tell that using a foldr would be useful here, I can put the . operator between each function in the list of functions and then apply it to val. However, I can't complete it, this is my attempt...
compFuncs :: [(a->a->a)] -> a -> a
compFuncs [] val = val
compFuncs (x:xs) val = foldr //Im lost here
Can someone help me out?
(I believe you intended to write the type as composeFuncs :: [a -> a] -> a -> a as this is how it is used.)
foldr works by replacing the constructors of a list with the replacements you specify. For example, foldr (+) 0 [1,2,3] works by taking the list [1,2,3], which is really constructed as 1:2:3:[], and replacing (:) with (+) and [] with 0 as follows:
1 : 2 : 3 : []
1 + 2 + 3 + 0
If you think about a list of functions [f,g,h] that you want to apply to some value as \x -> f (g (h x)), we can find a foldr by looking for replacements for (:) and []. First, let's use composition:
\x -> f (g (h x))
= (definition of (.))
\x -> (f . g . h) x
= (eta reduction)
f . g . h
This is close, but we must do something with the empty list constructor. We need to replace it with some sort of "do nothing" or "empty" function. Luckily, we have id, which is guaranteed not to change the result in any way:
f . g . h
= (definition of id)
f . g . h . id
Now we can see the fold:
f . g . h . id
f : g : h : []
and we write it as:
composeFuncs :: [a -> a] -> a -> a
composeFuncs = foldr (.) id
By the way, types that can be folded like this with an element that functions as an "identity" are known as monoids*, and a -> a is the Endo monoid.
* There is an additional requirement that the function used to combine values, like (.) for Endo or (+) for Sum, is associative. You'll notice that this allowed me to present them without needing parenthesis above.
Edit
For another way to discover this function, let's use GHC 7.8's new typed holes feature. First, we start with a definition of composeFuncs with some holes:
composeFuncs :: [a -> a] -> a -> a
composeFuncs = foldr _f _z
When GHC type checks this we get a type error, which I will reduce to the relevent lines:
tmp.hs:6:22: Found hole ‘_f’ with type: (a -> a) -> (a -> a) -> a -> a …
tmp.hs:6:25: Found hole ‘_z’ with type: a -> a …
Starting with _z, there is only one possible function of type a -> a, and that's id. For _f, we need a function that combines two functions to give a new function. That is, of course, (.), so we write:
composeFuncs :: [a -> a] -> a -> a
composeFuncs = foldr (.) id

Does haskell's foldr always take a two-parameter lambda?

Haskell newb here
I'm working on this problem in haskell:
(**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
* (compress '(a a a a b c c a a d e e e e))
(A B C A D E)
The solution (which I had to look up) uses foldr:
compress' :: (Eq a) => [a] -> [a]
compress' xs = foldr (\x acc -> if x == (head acc) then acc else x:acc) [last xs] xs
This foldr, according to the solution, takes two parameters, x and acc. It would seem like all foldr's take these parameters; is there any exception to this? Like a foldr that takes 3 or more? If not, is this convention redundant and can the formula be written with less code?
foldr takes a function of 2 arguments, but this doesn't prevent it from taking a function of 3 arguments provided that function has the right type signature.
If we had a function
g :: x -> y -> z -> w
With
foldr :: (a -> b -> b) -> b -> [a] -> b
Where we want to pass g to foldr, then (a -> b -> b) ~ (x -> y -> z -> w) (where ~ is type equality). Since -> is right associative, this means we can write g's signature as
x -> y -> (z -> w)
and its meaning is the same. Now we've produced a function of two parameters that returns a function of one parameter. In order to unify this with the type a -> b -> b, we just need to line up the arguments:
a -> | x ->
b -> | y ->
b | (z -> w)
This means that b ~ z -> w, so y ~ b ~ z -> w and a ~ x so g's type really has to be
g :: x -> (z -> w) -> (z -> w)
implying
foldr g :: (z -> w) -> [x] -> (z -> w)
This is certainly not impossible, although more unlikely. Our accumulator is a function instead, and to me this begs to be demonstrated with DiffLists:
type DiffList a = [a] -> [a]
append :: a -> DiffList a -> DiffList a
append x dl = \xs -> dl xs ++ [x]
reverse' :: [a] -> [a]
reverse' xs = foldr append (const []) xs $ []
Note that foldr append (const []) xs returns a function which we apply to [] to reverse a list. In this case we've given an alias to functions of the type [a] -> [a] called DiffList, but it's really no different than having written
append :: a -> ([a] -> [a]) -> [a] -> [a]
which is a function of 3 arguments.
As with all things in haskell have a look at the types of things to guide your way you can do this for any function in ghci.
Looking at this for foldr we see:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
This slightly abstract string can be written in english as:
foldr is a function that takes
1 ) a function with two parameters one of type a and one of type b and returns something of type b
2 ) A value of type b
3 ) A list of values of type a
And returns a value of type b
Where a and b are type variables (see here for a good tutorial on them) which can be filled in with any type you like.
It turns out that you can solve your compress problem using a foldr with a three-argument function.
compress :: Eq a => [a] -> [a]
compress [] = []
compress (z:zs) = z : foldr f (const []) zs z
where f x k w | x==w = k x
| otherwise = x : k x
Let's dissect that. First, we can improve readability by changing the last two lines to
where f x k = \w -> if x==w then k x else x : k x
This makes it evident that a ternary function is nothing but a binary function returning a unary function. The advantage of looking at it in this way is that foldr is best understood when passed a binary function. Indeed, we are passing a binary function, which just happens to return a function.
Let's focus on types now:
f :: a -> (a -> [a]) -> (a -> [a])
f x k
So, x::a is the element of the list we are folding on. Function k is the result of the fold on the list tail. The result of f x k is something having the same type as k.
\w -> if .... :: (a -> [a])
The overall idea behind this anonymous function is as follows. The parameter k plays the same role as acc in the OP code, except it is a function expecting the previous element w in the list before producing the accumulated compressed list.
Concretely, we use now k x when we used acc, passing on the current element to the next step, since by that time x will become the previous element w. At the top-level, we pass z to the function which is returned by foldr f (const []).
This compress variant is lazy, unlike the posted solution. In fact, the posted solution needs to scan the whole list before starting producing something: this is due to (\x acc -> ...) being strict in acc, and to the use of last xs. Instead, the above compress outputs list elements in a "streaming" fashion. Indeed, it works with infinite lists as well:
> take 10 $ compress [1..]
[1,2,3,4,5,6,7,8,9,10]
That being said, I think using a foldr here feels a bit weird: the code above is arguably less readable than the explicit recursion.

Resources