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
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
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]].
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) []
[]
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