Define bind without join for the list monad in Haskell - haskell

I understand the definition of >>= in term of join
xs >>= f = join (fmap f xs)
which also tells us that fmap + join yields >>=
I was wondering if for the List monad it's possible to define without join, as we do for example for Maybe:
>>= m f = case m of
Nothing -> Nothing
Just x -> f x

Sure. The actual definition in GHC/Base.hs is in terms of the equivalent list comprehension:
instance Monad [] where
xs >>= f = [y | x <- xs, y <- f x]
Alternatively, you could try the following method of working it out from scratch from the type:
(>>=) :: [a] -> (a -> [b]) -> [b]
We need to handle two cases:
[] >>= f = ???
(x:xs) >>= f = ???
The first is easy. We have no elements of type a, so we can't apply f. The only thing we can do is return an empty list:
[] >>= f = []
For the second, x is a value of type a, so we can apply f giving us a value of f x of type [b]. That's the beginning of our list, and we can concatenate it with the rest of the list generated by a recursive call:
(x:xs) >>= f = f x ++ (xs >>= f)

Related

apply a function n times to the n-th item in a list in haskell

I want a higher-order function, g, that will apply another function, f, to a list of integers such that
g = [f x1, f(f x2), f(f(f x3)), … , f^n(xn)]
I know I can map a function like
g :: (Int -> Int) -> [Int] -> [Int]
g f xs = map f xs
and I could also apply a function n-times like
g f xs = [iterate f x !! n | x <- xs]
where n the number of times to apply the function. I know I need to use recursion, so I don't think either of these options will be useful.
Expected output:
g (+1) [1,2,3,4,5] = [2,4,6,8,10]
You can work with explicit recursion where you pass each time the function to apply and the tail of the list, so:
g :: (Int -> Int) -> [Int] -> [Int]
g f = go f
where go _ [] = []
go fi (x:xs) = … : go (f . fi) xs
I here leave implementing the … part as an exercise.
Another option is to work with two lists, a list of functions and a list of values. In that case the list of functions is iterate (f .) f: an infinite list of functions that can be applied. Then we can implement g as:
g :: (Int -> Int) -> [Int] -> [Int]
g f = zipWith ($) (iterate (f .) f)
Sounds like another use for foldr:
applyAsDeep :: (a -> a) -> [a] -> [a]
applyAsDeep f = foldr (\x xs -> f x : map f xs) []
λ> applyAsDeep (+10) [1,2,3,4,5]
[11,22,33,44,55]
If you want to go a bit overkill ...
import GHC.Exts (build)
g :: (a -> a) -> [a] -> [a]
g f xs0 =
build $ \c n ->
let go x r fi = fi x `c` r (f . fi)
in foldr go (const n) xs0 f

Can my implementation of filter be improved?

An exercise in Haskell from First Principles says to implement filter using foldr and this is what I came up with but it feels and looks clunky. Is there a more natural way to implement it with a foldr?
import Data.Bool
myFilter :: (a -> Bool) -> [a] -> [a]
myFilter f = foldr (\x -> bool (++ []) ((:) x) (f x)) []
I would only use bool if it let me get rid of the lambda expression simply, by composing a call to bool with the predicate p: bool iffalse iftrue . p. However, p isn't the only function that needs to be called on a list element; (:) does as well. You could use the Applicative instance for functions, to write
myfilter p = foldr (bool id . (:) <*> p) [] -- yuck
but in this case I would just use a plain if expression, inside the lambda expression:
myfilter p = foldr (\x -> if p x then (x:) else id) [] -- much clearer!
Note that when specialized to functions, the Applicative's (<*>) operator is defined as f <*> g = \x -> f x (g x). I leave it as an exercise to use that definition to transform bool id . (:) <*> p into
\x -> bool id (x:) (p x).
You can use the Applicative instance of (->) a to make the lambda cleaner. But, if you want to use foldr, I don't think there's any substantial change you can effect:
myFilter f = foldr (bool id <$> (:) <*> f) []
bool id <$> (:) <*> f means \x -> bool id ((:) x) (f x). bool id has type ([a] -> [a]) -> Bool -> ([a] -> [a]). (:) has type a -> [a] -> [a], and f has type a -> Bool. When (<$>) and (<*>) are used in this way, you can think of it as pretending that (:) and f don't have an a argument, making them [a] -> [a] and Bool, respectively, applying them to bool id to get a [a] -> [a], and then ending the lie by reintroducing the a argument, making a a -> [a] -> [a]. The operators are in charge of threading that a around, so you don't need a lambda abstraction.
Rather than merely searching for a more elegant implementation, it would might help you more to learn an elegant process of searching for an implementation. This should make it simpler to find elegant solutions.
For any function h on lists we have that,
h = foldr f e
if and only if
h [] = e
h (x:xs) = f x (h xs)
In this case your h is filter p for some boolean function p that selects which elements to keep. Implementing filter p as a "simple" recursive function is not too hard.
filter p [] = []
filter p (x:xs) = if p x then x : (filter p xs) else (filter p xs)
The 1st line implies e = []. The 2nd line needs to be written in the form f x (filter p xs) to match the equation of h above, in order for us to deduce which f to plug in the foldr. To do that we just abstract over those two expressions.
filter p [] = []
filter p (x:xs) = (\x ys -> if p x then x : ys else ys) x (filter p xs)
So we have found that,
e = []
f x ys = if p x then x: ys else ys
It therefore follows,
filter p = foldr (\y ys -> if p y then y : ys else ys) []
To learn more about this method of working with foldr I recommend reading
"A tutorial on the universality and expressiveness of fold" by Graham Hutton.
Some added notes:
In case this seems overly complicated, note that while the principles above can be used in this "semi rigorous" fashion via algebraic manipulation, they can and should also be used to guide your intuition and aid you in informal development.
The equation for h (x:xs) = f x (h xs) sheds some clarity on how to find f. In the case where h is the filtering function you want an f which combines the element x with a tail that has already been filtered. If you really understand this it should be easy to arrive at,
f x ys = if p x then x : ys else ys
Yes, there is:
myFilter :: (a -> Bool) -> [a] -> [a]
myFilter f = foldMap (\x -> [x | f x])
> myFilter even [1..10]
[2,4,6,8,10]
See, I switched it on you, with foldMap.
Well, with foldr it is foldr (\x -> ([x | f x] ++)) [].

High order function thats has for input a list of functions and a list of elements and applies the functions to the elements

As the title suggests i am trying to implement a high order function declared as
Ord u => [v->u]->[v]->[u]
that has inputs a) a list of functions of any type and a range of values of any type and b) a list of elements of the same type and then it will return a list that is the result of all elements that occured from applying a function from the given list to an element from the given list in ascending order without repetitive values.
i was trying to implement it with the foldr function with no luck.
i thought that i can index with zip the functions as a pair so they will be applied one by one with the foldr function. bellow that i created a insertion sort so i can sort the final list
apply :: Ord u => [v->u]->[v]->[u]
apply f y = insSort (foldr(\(i, x) y -> x:y ) (zip [1..] f))
insSort :: Ord u => [u] -> [u]
insSort (h:t) = insert h (insSort t)
insSort [] = []
insert :: Ord u => u -> [u] -> [u]
insert n (h:t)
| n <= h = n : h : t
| otherwise = h : insert n t
insert n [] = [n]
for example some inputs with the output:
>apply [abs] [-1]
[1]
>apply [(^2)] [1..5]
[1,4,9,16,25]
>apply [(^0),(0^),(\x->div x x),(\x->mod x x)] [1..1000]
[0,1]
>apply [head.tail,last.init] ["abc","aaaa","cbbc","cbbca"]
"abc"
> apply [(^2),(^3),(^4),(2^)] [10]
[100,1000,1024,10000]
>apply [(*5)] (apply [(‘div‘5)] [1..100])
[0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100]
apply :: [a -> b] -> [a] -> [b]
First of all, this signature matches that of the standard <*> function, which is part of the Applicative class.
class Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Setting f ~ [] we have <*> :: [a -> b] -> [a] -> [b].
There are at least two sensible ways of writing an Applicative instance for lists. The first one takes the Cartesian product of its inputs, pairing every function with every value. If <*>'s input lists have length N and M, the output list will have length N*M. pure for this specification would put an element in a singleton list, so that pure id <*> xs = xs.
instance Applicative [] where
pure x = [x]
(f:fs) <*> xs = map f xs ++ (fs <*> xs)
This is equivalent to the standard Applicative instance for [].
The other sensible way of implementing Applicative zips the two lists together by applying functions to elements pointwise. If <*>'s input lists have length N and M, the output list will have length min(N, M). pure creates an infinite list, so once again pure id <*> xs = xs.
instance Applicative [] where
pure x = let xs = x:xs in xs
[] <*> _ = []
_ <*> [] = []
(f:fs) <*> (x:xs) = f x : (fs <*> xs)
This instance is available in base under the ZipList newtype.

Avoiding do statement in foldM

g ll =
foldlM (\ some_list b -> do
part <- f b
return (some_list ++ part)) [] ll
In above piece of code I use do statement just because the f function return a monad type: M a where a is a list.
( I "unpack" that list with <-. This is why I need do statement). Can I avoid it and write that more concisely? ( Yes, I know that I can write it using >>= but I also consider something nicer.)
foldlM is the wrong tool for the job. You can use it, as chepner's answer shows, but the way you're concatenating lists could get expensive. Luka Rahne's one-liner is much better:
g ll = fmap concat (mapM f ll)
Another option is to use foldr directly:
g = foldr (\x r -> (++) <$> f x <*> r) (pure [])
Another way to write the second version, by inlining the foldr:
g [] = pure []
g (x : xs) = (++) <$> f x <*> g xs
Your do expression
do
part <- f b
return (some_list ++ part)
follows the extract-apply-return pattern that fmap captures (due to the identity fmap f k = k >>= return . f
You extract part from the computation f b
You apply (some_list ++) to part
You return the result of that application.
This can be done in one step with fmap:
-- foldlM (f b >>= return . (some_list ++)) [] ll
foldlM (\some_list b -> fmap (some_list ++) (f b)) [] ll

How to define foldM using foldr/foldl (if it is possible)?

I wanted to make a generic function that folds over a wide range of inputs (see Making a single function work on lists, ByteStrings and Texts (and perhaps other similar representations)). As one answer suggested, the ListLike is just for that. Its FoldableLL class defines an abstraction for anything that is foldable. However, I need a monadic fold. So I need to define foldM in terms of foldl/foldr.
So far, my attempts failed. I tried to define
foldM'' :: (Monad m, LL.FoldableLL full a) => (b -> a -> m b) -> b -> full -> m b
foldM'' f z = LL.foldl (\acc x -> acc >>= (`f` x)) (return z)
but it runs out of memory on large inputs - it builds a large unevaluated tree of computations. For example, if I pass a large text file to
main :: IO ()
main = getContents >>= foldM'' idx 0 >> return ()
where
-- print the current index if 'a' is found
idx !i 'a' = print i >> return (i + 1)
idx !i _ = return (i + 1)
it eats up all memory and fails.
I have a feeling that the problem is that the monadic computations are composed in a wrong order - like ((... >>= ...) >>= ...) instead of (... >>= (... >>= ...)) but so far I didn't find out how to fix it.
Workaround: Since ListLike exposes mapM_, I constructed foldM on ListLikes by wrapping the accumulator into the state monad:
modifyT :: (Monad m) => (s -> m s) -> StateT s m ()
modifyT f = get >>= \x -> lift (f x) >>= put
foldLLM :: (LL.ListLike full a, Monad m) => (b -> a -> m b) -> b -> full -> m b
foldLLM f z c = execStateT (LL.mapM_ (\x -> modifyT (\b -> f b x)) c) z
While this works fine on large data sets, it's not very nice. And it doesn't answer the original question, if it's possible to define it on data that are just FoldableLL (without mapM_).
So the goal is to reimplement foldM using either foldr or foldl. Which one should it be? We want the input to be processed lazily and allow for infinte lists, this rules out foldl. So foldr is it going to be.
So here is the definition of foldM from the standard library.
foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM _ a [] = return a
foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
The thing to remember about foldr is that its arguments simply replace [] and : in the list (ListLike abstracts over that, but it still serves as a guiding principle).
So what should [] be replaced with? Clearly with return a. But where does a come from? It won’t be the initial a that is passed to foldM – if the list is not empty, when foldr reaches the end of the list, the accumulator should have changed. So we replace [] by a function that takes an accumulator and returns it in the underlying monad: \a -> return a (or simply return). This also gives the type of the thing that foldr will calculate: a -> m a.
And what should we replace : with? It needs to be a function b -> (a -> m a) -> (a -> m a), taking the first element of the list, the processed tail (lazily, of course) and the current accumulator. We can figure it out by taking hints from the code above: It is going to be \x rest a -> f a x >>= rest. So our implementation of foldM will be (adjusting the type variables to match them in the code above):
foldM'' :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM'' f z list = foldr (\x rest a -> f a x >>= rest) return list z
And indeed, now your program can consume arbitrary large input, spitting out the results as you go.
We can even prove, inductively, that the definitions are semantically equal (although we should probably do coinduction or take-induction to cater for infinite lists).
We want to show
foldM f a xs = foldM'' f a xs
for all xs :: [b]. For xs = [] we have
foldM f a []
≡ return a -- definition of foldM
≡ foldr (\x rest a -> f a x >>= rest) return [] a -- definition of foldr
≡ foldM'' f a [] -- definition of foldM''
and, assuming we have it for xs, we show it for x:xs:
foldM f a (x:xs)
≡ f a x >>= \fax -> foldM f fax xs --definition of foldM
≡ f a x >>= \fax -> foldM'' f fax xs -- induction hypothesis
≡ f a x >>= \fax -> foldr (\x rest a -> f a x >>= rest) return xs fax -- definition of foldM''
≡ f a x >>= foldr (\x rest a -> f a x >>= rest) return xs -- eta expansion
≡ foldr (\x rest a -> f a x >>= rest) return (x:xs) -- definition of foldr
≡ foldM'' f a (x:xs) -- definition of foldM''
Of course this equational reasoning does not tell you anything about the performance properties you were interested in.

Resources