Map then filter in Haskell - haskell

I want to Map an Integer type list in Haskell, and then if the map function returns Nothing I want to discard the result. The function I am trying to write will have a type signature of
mapThenFilter :: (Integer -> Maybe Integer) -> [Integer] -> [Integer]
and so far, I have thought of doing this:
checkIfNothing value = case value of
Just a -> a
Nothing -> 0
mapThenFilter = map checkIfNothing(map f l)
But this is incorrect. I am new to Haskell, so if possible can you advise me on where I am going wrong here? I believe since this is Map then Filter, the Haskell filter function is probably expected to be used too, however, I believe the outer map function in my function definition is doing the job intended(of the filter function)right?

As stated in the comments you are reimplementing mapMaybe.
Which is good. It is a non-obvious function, and it is good that you feel the need for it and came up with that idea, expressed in its type.
If you'd like to do it your way, you were off to a good start actually. Need to tweak it though:
checkIfNothing value = case value of
Just a -> a
Nothing -> 0
0 is too specific, let's go with []. But now simply returning a won't work. Let's put it in a list, too:
checkIfNothing :: Maybe t -> [t]
checkIfNothing value = case value of
Just a -> [a]
Nothing -> []
So that now,
mapThenFilter f l = map checkIfNothing (map f l)
is almost right. We produce our results in lists, and those that were skipped result in empty lists:
-- instead of
[ a, b, c, .... , z ]
-- we produce
[ [], [b], [], .... , [z] ]
and so we just need to concatenate them, to join them together with ++s:
[]++[b]++[]++...,++[z]
[ b, ...., z ]
And so we define
mapThenFilter :: (a1 -> Maybe a) -> [a1] -> [a]
mapThenFilter f l = concat $ map checkIfNothing (map f l)
By the way checkIfNothing also already exists. It is known as maybeToList:
> foo f l = concat $ map maybeToList $ map f l
foo :: (a1 -> Maybe a) -> [a1] -> [a]
> foo (\x -> listToMaybe [x | even x]) [1..10]
[2,4,6,8,10]
A combination of concat and map is important enough to have a special function assigned to do its job, concatMap. And that function is important enough to even be assigned a special operator, to do its job:
foo f = concat . map maybeToList . map f
= concat . map (maybeToList . f)
= concatMap (maybeToList . f)
= (maybeToList . f =<<)

Related

How can i fix this higher order function code in haskell?

I want to fix this code
h :: (a -> b) -> [a] -> [b]
h f = foldr (\x y -> f x : y) []
if i put h (+100) [1,2,3,4,5] in GHCI
it returns to me [101,202,303,404,505]
when i put h (*10) [1,2,3,4,5] then
i want to get [10,200,3000,40000,500000] list
can anyone help me fixing this code?
You here implemented a map, but in order to repeat the same operation multiple times, you need to perform a mapping on the tail y:
h :: (a -> a) -> [a] -> [a]
h f = foldr (\x y -> f x : map f y) []
Solving the general problem, as Willem Van Onsem's answer does, requires O(n^2) time to calculate the first n elements, because the function has to be applied k times to calculate the kth element.
To solve this sort of problem efficiently, you will need to take advantage of some additional structure. Based on your examples, I think the most obvious approach is to think about semigroup actions. That is, instead of applying an arbitrary function repeatedly, look for an efficient way to represent the compositions of the function. For example, (*x) can be represented by x, allowing (*x) . (*y) to be represented by x*y.
To apply this idea, we first need to transform Willem's solution to make the compositions explicit.
h :: (a -> a) -> [a] -> [a]
h f0 as0 = go as0 f0
where
go [] _ = []
go (a:as) f = f a : go as (f0 . f)
If we like, we can write that as a fold:
h :: (a -> a) -> [a] -> [a]
h f0 as = foldr go stop as f0
where
stop _ = []
go a r f = f a : r (f0 . f)
Now we've structured the function using an accumulator (which is a function). As we compose onto the accumulator, it will get slower and slower to apply it. We want to replace that accumulator with one we can "apply" quickly.
{-# language BangPatterns #-}
import Data.Semigroup
repeatedly :: Semigroup s => (s -> a -> a) -> s -> [a] -> [a]
repeatedly act s0 as = foldr go stop as s0
where
stop _ = []
go a r !s = act s a : r (s0 <> s)
Now you can use, for example,
repeatedly (\(Product s) -> (s*)) (Product 10) [1..5]
==> [10,200,3000,40000,500000]
repeatedly (\(Sum s) -> (s+)) (Sum 100) [1..5]
==> [101,202,303,404,505]
In each of these, you accumulate a product/sum which is added to/multiplied by the current list element.

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

Trouble explaining Haskell code with where and pattern match

I have hard time parsing how mf m y are assigned values or even why there can be 3 variables on the left side of assignment in where section.
Q: Can anyone explain what happens here in both cases? (that is for empty list and a list with some elements)
-- | A variant of 'foldl' that has no base case,
-- and thus may only be applied to non-empty structures.
--
-- #'foldl1' f = 'List.foldl1' f . 'toList'#
foldl1 :: (a -> a -> a) -> t a -> a
foldl1 f xs = fromMaybe (errorWithoutStackTrace "foldl1: empty structure")
(foldl mf Nothing xs)
where
mf m y = Just (case m of
Nothing -> y
Just x -> f x y)
(this is the source code for the foldl1 function).
Definitions in where clauses follow the same syntax as global definitions, so mf m y = ... defines a function named mf, which takes parameters named m and y.
I have hard time parsing how mf m y are assigned values or even why there can be 3 variables.
You do not define three variables here: you define a variable mf which is a function, and m and y are two arguments of the function mf.
We can make the function more elegant, and thus omit the m and y. mf can be defined as:
mf Nothing = Just . id
mf (Just x) = Just . f x
Mind that we can not simply make mf an outer function, since it uses a function f, with is a parameter of foldl1. So we put it in a where clause:
foldl1 :: (a -> a -> a) -> t a -> a
foldl1 f xs = fromMaybe (errorWithoutStackTrace "foldl1: empty structure")
(foldl mf Nothing xs)
where mf Nothing = Just . id
mf (Just x) = Just . f x
In the empty list case, foldl mf Nothing [] ~ Nothing by definition, so foldl1 will return the "empty structure" error.
When xs is not empty, then foldl1' is simply a left fold by foldl. In this case foldl has the type
foldl :: (Maybe a -> a -> Maybe a) -> Maybe a -> [a] -> Maybe a
which makes use of the combining function mf :: Maybe a -> a -> Maybe a defined in the where clause.

Taking a list of lists and generating all variants with one element replaced [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have types for a two-dimensional map of characters:
type Row = [Char]
type Mappy = [Row]
I'd like to write a function that takes a Mappy like:
[['o','o'],['o','o']]
and generates a list of all Mappys with a single 'o' element replaced with 'i':
[ [['i','o'],['o','o']]
, [['o','i'],['o','o']]
, [['o','o'],['i','o']]
, [['o','o'],['o','i']]
]
Here's what I've tried: I think I need to use the map function, because I need to go over each element, but I don't know how, because a map function doesn't keep track of the position it is working on.
type Row = [Char]
type Mappy = [Row]
func :: Mappy -> [Mappy]
func a = map (map someFunc a) a
someFunc :: Mappy -> Char -> Mappy
someFunc a b = if b == "o"
then undefined
else a
Obviously, I should change the undefined, but i have no idea how. Thanks in advance.
Zippers are great, and there's an interesting blog post about
implementing Conway's Game of Life using zippers and comonads in Haskell. On the other
hand, if this is still your first week learning Haskell, you might
want to save Comonads for Thursday, right?
Here's another approach that uses simple recursion and list
comprehensions and no complex Haskell features.
First, imagine we have an awesome function:
varyOne :: (a -> [a]) -> [a] -> [[a]]
varyOne = undefined
that works as follows. Given a function f that produces zero or
more variants of an element a, the function call varyOne f xs
generates all variants of the list xs that result from taking
exactly one element of xs, say x in the middle of the list, and replacing it with all the
variants given by f x.
This function is surprisingly flexible. It can generate the list of all variants resulting from forcibly replacing an element by a constant:
> varyOne (\x -> [3]) [1,2,3,4]
[[3,2,3,4],[1,3,3,4],[1,2,3,4],[1,2,3,3]]
By returning a singleton variant for a specific value and an empty list of variants for other values, it can generate all variants that replace an 'o' with an 'i' while suppressing the "variants" where no replacement is possible:
> let varyRow = varyOne (\c -> if c == 'o' then ['i'] else [])
> varyRow "ooxo"
["ioxo","oixo","ooxi"]
and, because varyRow itself generates variants of a row, it can be used with varyOne to generate variants of tables where a particular row has been replaced by its possible variants:
> varyOne varyRow ["ooo","oox","ooo"]
[["ioo","oox","ooo"],["oio","oox","ooo"],["ooi","oox","ooo"],
["ooo","iox","ooo"],["ooo","oix","ooo"],
["ooo","oox","ioo"],["ooo","oox","oio"],["ooo","oox","ooi"]]
It turns out that this awesome function is surprisingly easy to write:
varyOne :: (a -> [a]) -> [a] -> [[a]]
varyOne f (x:xs)
= [y:xs | y <- f x] ++ [x:ys | ys <- varyOne f xs]
varyOne _ [] = []
The first list comprehension generates all the variants for the current element. The second list comprehension generates variants that involve changes to the right of the current element using a recursive varyOne call.
Given varyOne, we can define:
replaceOne :: Char -> Char -> Mappy -> [Mappy]
replaceOne old new = varyOne (varyOne rep1)
where rep1 x = if x == old then [new] else []
and:
> replaceOne 'o' 'i' ["ooo","oox","ooo"]
[["ioo","oox","ooo"],["oio","oox","ooo"],["ooi","oox","ooo"]
,["ooo","iox","ooo"],["ooo","oix","ooo"]
,["ooo","oox","ioo"],["ooo","oox","oio"],["ooo","oox","ooi"]]
is probably the function you're looking for.
If you prefer to unconditionally replace a single element with i, no matter what the old element was, then this will work:
> varyOne (varyOne (const ['i'])) ["ooo","oox","ooo"]
[["ioo","oox","ooo"],["oio","oox","ooo"],["ooi","oox","ooo"]
,["ooo","iox","ooo"],["ooo","oix","ooo"],["ooo","ooi","ooo"]
,["ooo","oox","ioo"],["ooo","oox","oio"],["ooo","oox","ooi"]]
What you want, young BaasBartMans, is a Zipper.
data Zipper a = Zipper [a] a [a]
ofList :: [a] -> Maybe (Zipper a)
ofList [] = Nothing
ofList (a:as) = Just (Zipper [] a as)
A zipper gives you the context for a position in a list, so you
can easily modify them one at a time, step forward and backward and such.
We can recover a list from a zipper:
instance Foldable Zipper where
foldr f c (Zipper ls a rs) = foldl' (flip f) (f a (foldr f c rs)) ls
We can modify every position in a Zipper simultaneously:
instance Functor Zipper where
fmap f (Zipper ls a rs) = Zipper (fmap f ls) (f a) (fmap f rs)
Or just the focused element:
here :: Functor f => (a -> f a) -> Zipper a -> f (Zipper a)
here f (Zipper ls a rs) = fmap (\a' -> Zipper ls a' rs) (f a)
And as a Zipper is a Comonad, we can modify each element in context:
instance Comonad Zipper where
extract (Zipper _ a _) = a
extend f z#(Zipper ls a rs) = Zipper ls' a' rs' where
a' = f z
ls' = unfoldr (fmap (\z' -> (f z', z')) . goLeft) z
rs' = unfoldr (fmap (\z' -> (f z', z')) . goRight) z
Using that, we can build a function that modifies each element of a list in context:
everywhere :: Alternative f => (a -> f a) -> [a] -> f [a]
everywhere f as = case ofList as of
Nothing -> pure []
Just z -> asum $ extend (fmap toList . here f) z
Which works for simple lists:
λ everywhere (\a -> [a+1]) [10,20,30]
[[11,20,30]
,[10,21,30]
,[10,20,31]]
And nested lists:
λ everywhere (everywhere (\a -> [a+1])) [[10], [20,20], [30,30,30]]
[[[11],[20,20],[30,30,30]]
,[[10],[21,20],[30,30,30]]
,[[10],[20,21],[30,30,30]]
,[[10],[20,20],[31,30,30]]
,[[10],[20,20],[30,31,30]]
,[[10],[20,20],[30,30,31]]]

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

Resources