Trying to implement elem with a foldl any - haskell

I am new in haskell, i am trying right now to implement "elem" with a "foldl any" in Haskell, but it won't work.
My any :
any' p = foldl' (\y x -> p x || y) False
and this is my elem :
elem' y = foldl' (\z x -> x==y || z) False
my first try was this :
elemfa p y = not (any' (\x -> not (p x)) y)
but i am getting an error everytime

Your elemfa :: Foldable f => (a -> Bool) -> f a -> Bool makes use of any'''', but that function does not exists. If you rewrite this to:
elemfa :: Foldable f => (a -> Bool) -> f a -> Bool
elemfa p y = not (any' (\x -> not (p x)) y)
You can make it more clean with:
elemfa :: Foldable f => (a -> Bool) -> f a -> Bool
elemfa p = not . any' (not . p)
It will at least produce output. This function will check if all elements satisfy the given predicate.
That being said, it is not ideal to use a foldl here for any, elem and elemfa, since that means it will keep iterating over the list, even if it found an element that satisfies the predicate. If you thus work on an infinite list, it will not return True, even if it found an element:
Prelude Data.List> elem' 1 (1 : repeat 2)
… keeps looking …
Here foldr :: Foldable f => (a -> b -> b) -> b -> f a -> b can be used to stop searching once the element has been found, for example:
any' :: Foldable f => (a -> Bool) -> f a -> Bool
any' p = foldr (\x -> (p x ||)) False
elem' :: (Foldable f, Eq a) => a -> f a -> Bool
elem' x = any' (x==)
all' :: Foldable f => (a -> Bool) -> f a -> Bool
all' p = not . any (not . p)

Related

Applying f to each element and return the result as list

I want that my function someZip returns the resulting list from applying f to each element.
This is what I got so far:
someZip :: (a -> b -> c -> d) -> [(a,b,c)] -> [d]
someZip f (x:xs) (y:ys) (z:zs) = f x y z : someZip f xs ys zs
I've tried different approaches, but I can't find a solution to this problem.
I am completly lost right now, what am I missing here?
The function you've written and the type signature you've targeted are incongruous. If you like the type signature, you need to alter the definition
someZip :: (a -> b -> c -> d) -> [(a,b,c)] -> [d]
someZip _ [] = []
someZip f ((x,y,z):ts) = f x y z : someZip f ts
This, incidentally, can be written in terms of fmap.
someZip :: (a -> b -> c -> d) -> [(a,b,c)] -> [d]
someZip f = fmap (\(x, y, z) -> f x y z)
If you prefer to keep the implementation and change the type signature, you'll need to take more arguments
someZip :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
someZip f (x:xs) (y:ys) (z:zs) = f x y z : someZip f xs ys zs
someZip _ _ _ _ = []
Incidentally, this function is actually zipWith3
someZip :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
someZip = zipWith3

A map function that operates on pairs

I am trying to write a function which is like map, but which takes functions of type (a, a) -> b as its first argument. However, I get the error
<interactive>:474:11: error:
Parse error in pattern: \ (x, y) -> f x y
with the following code:
Prelude> :{
Prelude| mappairs :: ((a, a) -> b) -> [a] -> [b]
Prelude| mappairs (\(x,y) -> f x y) xs = foldr (\(x, y) acc -> (f x y : acc)) [] xs
Prelude| :}
What is the problem?
The pattern:
\(x,y) -> f x y
in the clause:
mappairs (\(x,y) -> f x y) xs = foldr (\(x, y) acc -> (f x y : acc)) [] xs
is indeed not valid, since (->) is not a data constructor.
You can however use zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] here:
mappairs :: ((a, a) -> b) -> [a] -> [b]
mappairs _ [] = []
mappairs f xa#(_:xs) = zipWith (curry f) xa xs
For example:
> mappairs (\(x,y) -> x+y) [1,4,2,5]
[5,6,7]
But it looks more "Haskell-ish" to omit the tuples, and thus use a function directly:
mappairs :: (a -> a -> b) -> [a] -> [b]
mappairs _ [] = []
mappairs f xa#(_:xs) = zipWith f xa xs

Why does zipWith.zipWith work?

I am implementing a function combine :: [[a]] -> [[b]] -> (a -> b -> c) -> [[c]] which given two 2D lists, applies a given function f :: a -> b -> c to the entries of the 2D list. In other words:
[[a, b, c], [[r, s, t], [[f a r, f b s, f c t],
combine [d, e, g], [u, v, w], f = [f d u, f e v, f g w],
[h, i, j]] [x, y, z]] [f h x, f i y, f j z]]
Now I suspect that combine = zipWith . zipWith, because I have tried it out and it is giving me the intended results, e.g.
(zipWith . zipWith) (\x y -> x+y) [[1,2,3],[4,5,6]] [[7,8,9],[10,11,12]]
gives the expected result [[8,10,12],[14,16,18]], but I cannot understand why this works, because I don't understand how the type of zipWith . zipWith turns out to be (a -> b -> c) -> [[a]] -> [[b]] -> [[c]].
Is (.) here still carrying out the usual function composition? If so, can you explain how this applies to zipWith?
To infer the type of an expression such as zipWith . zipWith, you can simulate the unification in your head the following way.
The first zipWith has type (a -> b -> c) -> ([a] -> [b] -> [c]), the second (s -> t -> u) -> ([s] -> [t] -> [u]) and (.) has type (m -> n) -> (o -> m) -> (o -> n).
For it to typecheck, you need:
m = (a -> b -> c)
n = ([a] -> [b] -> [c])
o = (s -> t -> u)
m = ([s] -> [t] -> [u]) => a = [s], b = [t], c = [u] because of the first constraint
Then the returned type is o -> n which is (s -> t -> u) -> ([a] -> [b] -> [c]) from the constraints and going one step further (s -> t -> u) -> ([[s]] -> [[t]] -> [[u]]).
Another way of seeing it is that lists with the zipping operation form an Applicative, and the composition (nesting) of Applicatives is still Applicative:
λ import Control.Applicative
λ import Data.Functor.Compose
λ let l1 = ZipList [ZipList [1,2,3], ZipList [4,5,6]]
λ let l2 = ZipList [ZipList [7,8,9], ZipList [10,11,12]]
λ getCompose $ (+) <$> Compose l1 <*> Compose l2
ZipList {getZipList = [ZipList {getZipList = [8,10,12]},
ZipList {getZipList = [14,16,18]}]}
The ZipList newtype is required because "bare" lists have a different Applicative instance, which forms all combinations instead of zipping.
Yes, . is the normal function composition operator:
Prelude> :type (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
One way to look at it is that it takes an a value, first calls the a -> b function, and then uses the return value of that function to call the b -> c function. The result is a c value.
Another way to look at (zipWith . zipWith), then, is to perform an eta expansion:
Prelude> :type (zipWith . zipWith)
(zipWith . zipWith) :: (a -> b -> c) -> [[a]] -> [[b]] -> [[c]]
Prelude> :t (\x -> zipWith $ zipWith x)
(\x -> zipWith $ zipWith x)
:: (a -> b -> c) -> [[a]] -> [[b]] -> [[c]]
Prelude> :t (\x -> zipWith (zipWith x))
(\x -> zipWith (zipWith x))
:: (a -> b -> c) -> [[a]] -> [[b]] -> [[c]]
The type of zipWith itself:
Prelude> :type zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
So, in the above lambda expression, x must be (a -> b -> c), and hence zipWith x must have the type [a] -> [b] -> [c].
The outer zipWith also needs a function (a1 -> b1 -> c1), which matches zipWith x if a1 is [a], b1 is [b], and c1 is [c].
So, by replacement, zipWith (zipWith x) must have the type [[a]] -> [[b]] -> [[c]], and therefore the type of the lambda expression is (a -> b -> c) -> [[a]] -> [[b]] -> [[c]].

Haskell: Defining map function using unfold

I have the following Haskell method
unfold :: (a -> Bool) -> (a -> b) -> (a -> a) -> a -> [b]
unfold p h t x
| p x = []
| otherwise = (h x):(unfold p h t (t x))
How can i define the regular prelude map f x method using this given unfold method.
If you define:
map' :: (a -> b) -> [a] -> [b]
map' f = unfold null (f.head) tail
then
\> map' show [1..5]
["1","2","3","4","5"]
\> map' (+1) []
[]

relation between monadic filter and fold

Many higher-order functions can be defined in term of the fold function. For example, here is the relation between filter and foldl in Haskell.
myFilter p [] = []
myFilter p l = foldl (\y x -> if (p x) then (x:y) else y) [] (reverse l)
Is there a similar relation between their monadic versions filterM and foldM ? How can I write filterM in term of foldM ?
I tried hard to find a monadic equivalent to \y x -> if (p x) then (x:y) else y to plug into foldM without success.
Like in D.M.'s answer, only without the reverse. Let the types guide you:
import Control.Monad
{-
foldM :: (Monad m) => (b -> a -> m b) -> b -> [a] -> m b
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
-}
filtM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
filtM p xs = foldM f id xs >>= (return . ($ []))
where
f acc x = do t <- p x
if t then return (acc.(x:)) else return acc
Not sure that it has any sense (since it has that strange reverse), but at least it type checked well:
myFilterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
myFilterM p l = foldM f [] (reverse l)
where
f y x = do
p1 <- p x
return $ if p1 then (x:y) else y

Resources