Haskell - creating a function definition for the function `all` using foldr - haskell

I'm trying to create a function definition for the function all using foldr. p is the predicate. I know this can be done:
all p = and . foldr (\x xs -> p x : xs) []
But what I want to do is to shift the function and into the foldr equation. Can this be done?
I've tried the following, which all failed to work:
all p = foldr (\x p -> \ys -> and (p x) ys) True
all p = foldr (\x and -> (\ys -> (p x and ys))) True
all p = foldr (\x ys -> and . (p x) ys) True
Am I falling short in my understanding of how to apply foldr?

We have
all p = and
. foldr (\x xs -> p x : xs) []
= foldr (&&) True -- {y : ys} -> y && {ys} 2-3
. foldr (\x xs -> p x : xs) [] -- {x , xs} -> p x : {xs} 1-2
= foldr (\x xs -> p x && xs) True -- {x , xs} -> p x && {xs} 1---3
because folding replaces each constructor with the specified combination operation (aka reducer), and replacing a cons of an element with a cons of a modified element, and then replacing that cons with (&&), is just replacing a cons of an element with the (&&) of a modified element right away:
a : ( b : ( c : ( d : ( ... )))) _OR_ [] -- | | 1
-- | |
p a : (p b : (p c : (p d : ( ... )))) _OR_ [] -- ↓ | | 2
-- | |
p a && (p b && (p c && (p d && ( ... )))) _OR_ True -- ↓ ↓ 3
In other words, folds compose by fusing their reducer functions, and reducer functions fuse by replacing the {constructors they use} with the next fold's reducer in the chain of folds, so that their corresponding transducers compose (as in Clojure's transducers); thus,
= foldr (reducingWith (&&)) True
. foldr ((mapping p) (:)) []
= foldr ((mapping p) (reducingWith (&&))) True
= foldr ((mapping p . reducingWith) (&&) ) True
-- first map p, then reduce with (&&)
for the appropriate definitions of reducingWith and mapping:
reducingWith cons x xs = cons x xs
mapping f cons x xs = cons (f x) xs
filtering p cons x xs | p x = cons x xs
| otherwise = xs
concatting t cons x xs = foldr cons xs (t x)

Related

Using foldr to define map (develop)

Having a hard time understanding fold... Is the expansion correct ? Also would appreciate any links, or analogies that would make fold more digestible.
foldMap :: (a -> b) -> [a] -> [b]
foldMap f [] = []
foldMap f xs = foldr (\x ys -> (f x) : ys) [] xs
b = (\x ys -> (f x):ys)
foldMap (*2) [1,2,3]
= b 1 (b 2 (foldr b [] 3))
= b 1 (b 2 (b 3 ( b [] [])))
= b 1 (b 2 ((*2 3) : []))
= b 1 ((*2 2) : (6 :[]))
= (* 2 1) : (4 : (6 : []))
= 2 : (4 : (6 : []))
First, let's not use the name foldMap since that's already a standard function different from map. If you want to re-implement an existing function with the same or similar semantics, convention is to give it the same name but either in a separate module, or with a prime ' appended to the name. Also, we can omit the empty-list case, since you can just pass that to the fold just as well:
map' :: (a -> b) -> [a] -> [b]
map' f xs = foldr (\x ys -> f x : ys) [] xs
Now if you want to evaluate this function by hand, first just use the definition without inserting anything more:
map' (*2) [1,2,3,4]
≡ let f = (*2)
xs = [1,2,3,4]
in foldr (\x ys -> (f x) : ys) [] xs
≡ foldr (\x ys -> (*2) x : ys) [] [1,2,3,4]
Now just prettify a bit:
≡ foldr (\x ys -> x*2 : ys) [] [1,2,3,4]
Now to evaluate this through, you also need the definition of foldr. It's actually a bit different in GHC, but effectively
foldr _ z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
So with your example
...
≡ foldr (\x ys -> x*2 : ys) [] (1:[2,3,4])
≡ (\x ys -> x*2 : ys) 1 (foldr (\x ys -> x*2 : ys) [] [2,3,4])
Now we can perform a β-reduction:
≡ 1*2 : foldr (\x ys -> x*2 : ys) [] [2,3,4]
≡ 2 : foldr (\x ys -> x*2 : ys) [] [2,3,4]
...and repeat for the recursion.
foldr defines a family of equations,
foldr g n [] = n
foldr g n [x] = g x (foldr g n []) = g x n
foldr g n [x,y] = g x (foldr g n [y]) = g x (g y n)
foldr g n [x,y,z] = g x (foldr g n [y,z]) = g x (g y (g z n))
----- r ---------
and so on. g is a reducer function,
g x r = ....
accepting as x an element of the input list, and as r the result of recursively processing the rest of the input list (as can be seen in the equations).
map, on the other hand, defines a family of equations
map f [] = []
map f [x] = [f x] = (:) (f x) [] = ((:) . f) x []
map f [x,y] = [f x, f y] = ((:) . f) x (((:) . f) y [])
map f [x,y,z] = [f x, f y, f z] = ((:) . f) x (((:) . f) y (((:) . f) z []))
= (:) (f x) ( (:) (f y) ( (:) (f z) []))
The two families simply exactly match with
g = ((:) . f) = (\x -> (:) (f x)) = (\x r -> f x : r)
and n = [], and thus
foldr ((:) . f) [] xs == map f xs
We can prove this rigorously by mathematical induction on the input list's length, following the defining laws of foldr,
foldr g n [] = []
foldr g n (x:xs) = g x (foldr g n xs)
which are the basis for the equations at the top of this post.
Modern Haskell has Fodable type class with its basic fold following the laws of
fold(<>,n) [] = n
fold(<>,n) (xs ++ ys) = fold(<>,n) xs <> fold(<>,n) ys
and the map is naturally defined in its terms as
map f xs = foldMap (\x -> [f x]) xs
turning [x, y, z, ...] into [f x] ++ [f y] ++ [f z] ++ ..., since for lists (<>) == (++). This follows from the equivalence
f x : ys == [f x] ++ ys
This also lets us define filter along the same lines easily, as
filter p xs = foldMap (\x -> [x | p x]) xs
To your specific question, the expansion is correct, except that (*2 x) should be written as ((*2) x), which is the same as (x * 2). (* 2 x) is not a valid Haskell (though valid Lisp :) ).
Functions like (*2) are known as "operator sections" -- the missing argument goes into the empty slot: (* 2) 3 = (3 * 2) = (3 *) 2 = (*) 3 2.
You also asked for some links: see e.g. this, this and this.

Recursive definitions of scanl and scanr in Haskell

I have searched but cannot find simple definitions of the functions scanr and scanl, only explanations that they show the intermediate calculations of the functions foldr and foldl (respectively).
I have written a recursive definition for scanl, based on the foldl property foldl f y (x:xs) = foldl f (f y x) xs:
scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' f x [] = [x]
scanl' f x (y:ys) = x : scanl' f (f x y) ys
This seems to work. However, there is a type error when I try to apply this analogy with the foldr property foldr f y (x:xs) = f x (foldr f y xs):
scanr' :: (a -> b -> b) -> b -> [a] -> [b]
scanr' _ x [] = [x]
scanr' f x (y:ys) = y : f x (scanr' f x ys)
This fails as the second input for f needs to be a b not a [b]. However, I am unsure how to do this while also recursing on scanr'.
To compute
result = scanr' f x (y:ys)
you must have computed
partialResult = scanr' f x ys
after which you get
result = (y `f` head partialResult) : partialResult
The complete implementation is
scanr' _ x [] = [x]
scanr' f x (y:ys) = (y `f` head partialResult) : partialResult
where partialResult = scanr' f x ys
scanl1 (\acc x -> if x > acc then x else acc)[3,4,5,3,7,9,2,1]
from Learn You A Haskell seems to have only two arguments: the function and the list. Yet it works. It even works if you write it as:
scanl1 (\x acc -> if x > acc then x else acc)[3,4,5,3,7,9,2,1]
Slightly puzzling why works.

Strictness of pattern matching vs. deconstructing

I'm trying to define primitive recursion in term of foldr, as explained in A tutorial on the universality and expressiveness on fold chapter 4.1.
Here is first attempt at it
simpleRecursive f v xs = fst $ foldr g (v,[]) xs
where
g x (acc, xs) = (f x xs acc,x:xs)
However, above definition does not halt for head $ simpleRecursive (\x xs acc -> x:xs) [] [1..]
Below is definition that halt
simpleRecursive f v xs = fst $ foldr g (v,[]) xs
where
g x r = let (acc,xs) = r
in (f x xs acc,x:xs)
Given almost similar definition but different result, why does it differ? Does it have to do with how Haskell pattern match?
The crucial difference between the two functions is that in
g x r = let (acc, xs) = r
in (f x xs acc, x:xs)
The pattern match on the tuple constructor is irrefutable, whereas in
g x (acc, xs) = (f x xs acc, x:xs)
it is not. In other words, the first definition of g is equivalent to
g x ~(acc, xs) = (f x xs acc, x:xs)

Haskell: How to use let-in construction?

I wrote a sort function. It's pretty weird.
sort :: (Eq a, Ord a) => [a] -> [a]
sort xs = repeat'' sort' (xs) (length xs)
repeat'' f xs 0 = xs
repeat'' f xs n = repeat'' f (f xs) (n-1)
sort' (x:y:xs)
| x < y = y : sort' (x:xs)
| otherwise = x : sort' (y:xs)
sort' x = x
How can I prettify it using let-in construction?
I think my try doesn't look good:
sort :: (Eq a, Ord a) => [a] -> [a]
sort xs = let
r f xs 0 = xs
r f xs n = r f (f xs) (n-1)
in r f' xs $ length xs where
f' (x:y:xs) | x < y = y : f' (x:xs)
| otherwise = x : f' (y:xs)
f' a = a

How can i make Insert_sort high-order-function in Haskell

plz watch my code
insert x [] = [x]
insert x (y:ys)
| x < y = x:y:ys
| x == y = y:ys ++ [x]
| otherwise = y:insert x ys
insert_sort [] = []
insert_sort (x:xs) = insert x (insert_sort xs)
insert_pair (x,y) [] = [(x,y)]
insert_pair (x,y) ((a,b):yd)
| x > a = (a,b):insert_pair (x,y) yd
| otherwise = (x,y):(a,b):yd
insert_sort_pair [] = []
insert_sort_pair (x:xs) = insert_pair x (insert_sort_pair xs)
insert_high f [] = []
insert_high f (x:y:ys)
| f x y = x:y:ys
| otherwise = y:insert x ys
insert_high f ((a,b):(c,d):yd)
| f a c = (a,b):insert_pair (c,d) yd
| otherwise = (a,b):(c,d):yd
insert_sort_high f [] = []
insert_sort_high f (x:xs) = insert_high (f) x (insert_sort_high (f) xs)
I want to make insert_sort-high can do both insert_sort and insert_pair_sort.
"insert_sort_pair" compare the number in (number,symbol).
For example:
insert_sort_high (<) [3,5,2,1,4] -> [1,2,3,4,5]
insert_sort_high (>) [(2,'a'),(3,'b'),(1,'c')] -> [(1,'c'),(2,'a'),(3,'b')]
But, it doesn't work... how can i fix it?
First, a fundamental misunderstanding.
Write a type for insert_high - it should probably be (a -> a -> Bool) -> [a] -> [a]. But you've written a specialization for lists of tuples, so you've forced it to be less general than that.
You can only cover the general case. You're being misled by your examples.
I'd argue what you really want is
λ insert_sort_high (<) [3,5,2,1,4]
[1,2,3,4,5]
λ insert_sort_high (\(x,y) (a,b) -> x < a) [(2,'a'), (3,'b'), (1,'c')]
[(1,'c'),(2,'a'),(3,'b')]
The latter can be written a little more easily as
λ :m +Data.Function
λ insert_sort_high ((<) `on` fst) [(2,'a'), (3,'b'), (1,'c')]
[(1,'c'),(2,'a'),(3,'b')]
Of course, that's only if you only want sorting to be on the first element of the pair.
λ insert_sort_high ((<) `on` fst) [(2,'a'), (3,'b'), (1, 'a'), (1,'b'), (1,'c'), (1,'a')]
[(1,'a'),(1,'c'),(1,'b'),(1,'a'),(2,'a'),(3,'b')]
If you want to sort by the entire pair, you can do that too
λ (1,'a') < (1,'b')
True
λ (1,'z') < (2,'a')
True
λ insert_sort_high (<) [(2,'a'), (3,'b'), (1,'a'),(1,'b'),(1,'c'), (1,'a')]
[(1,'a'),(1,'a'),(1,'b'),(1,'c'),(2,'a'),(3,'b')]
But I digress.
With that in mind all you really need to do is delete your tuple case, and clean up some typos.
insert_high :: (a -> a -> Bool) -> a -> [a] -> [a]
insert_high _ x [] = [x]
insert_high f x (y:ys)
| f x y = x:y:ys
| otherwise = y : insert_high f x ys
insert_sort_high _ [] = []
insert_sort_high f (x:xs) = insert_high f x (insert_sort_high f xs)

Resources