I'm learning Haskell and I'm doing now an exercise with the Maybe Class. I have to create a function which applies f("Maybe function") to a(and its following results) repeatedly until f a returns Nothing.
For example f a0 = Just a1,f a1= Just a2,...,f an = Nothing. Then
unfold f a0 = [a0,a1,...,an]
I've tried to do it and and I've got:
unfold :: (a- > Maybe a) -> a -> [a]
unfold f a = case f a of
Just n -> n: unfold f a
Nothing -> []
The problem is that the solution is:
unfold' :: ( a -> Maybe a) -> a -> [a]
unfold' f a = a : rest ( f a )
where rest Nothing = []
rest ( Just x ) = unfold' f x
And my program doesn't work like the solution. Maybe I'm using wrong "case of" but I'm not sure.
Your use of case is fine, but have a look where you cons the new value on the list, and where the solution does.
testFunc = const Nothing
unfold testFunc 1 == [] -- your version prepends only if f a isn't Nothing
unfold' testFunc 1 == [1] -- the solution _always_ prepends the current value
Also, you're using the same value all the time.
unfold :: (a -> Maybe a) ->a -> [a]
unfold f a = a : case f a of -- cons before the case
Just n -> unfold f n -- use n as parameter for f
Nothing -> []
Related
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 =<<)
I would like to define a greaters function, which selects from a list items that are larger than the one before it.
For instance:
greaters [1,3,2,4,3,4,5] == [3,4,4,5]
greaters [5,10,6,11,7,12] == [10,11,12]
The definition I came up with is this :
greaters :: Ord a => [a] -> [a]
Things I tried so far:
greaters (x:xs) = group [ d | d <- xs, x < xs ]
Any tips?
We can derive a foldr-based solution by a series of re-writes starting from the hand-rolled recursive solution in the accepted answer:
greaters :: Ord a => [a] -> [a]
greaters [] = []
greaters (x:xs) = go x xs -- let's re-write this clause
where
go _ [] = []
go last (act:xs)
| last < act = act : go act xs
| otherwise = go act xs
greaters (x:xs) = go xs x -- swap the arguments
where
go [] _ = []
go (act:xs) last
| last < act = act : go xs act
| otherwise = go xs act
greaters (x:xs) = foldr g z xs x -- go ==> foldr g z
where
foldr g z [] _ = []
foldr g z (act:xs) last
| last < act = act : foldr g z xs act
| otherwise = foldr g z xs act
greaters (x:xs) = foldr g z xs x
where -- simplify according to
z _ = [] -- foldr's definition
g act (foldr g z xs) last
| last < act = act : foldr g z xs act
| otherwise = foldr g z xs act
Thus, with one last re-write of foldr g z xs ==> r,
greaters (x:xs) = foldr g z xs x
where
z = const []
g act r last
| last < act = act : r act
| otherwise = r act
The extra parameter serves as a state being passed forward as we go along the input list, the state being the previous element; thus avoiding the construction by zip of the shifted-pairs list serving the same purpose.
I would start from here:
greaters :: Ord a => [a] -> [a]
greaters [] = []
greaters (x:xs) = greatersImpl x xs
where
greatersImpl last [] = <fill this out>
greatersImpl last (x:xs) = <fill this out>
The following functions are everything you’d need for one possible solution :)
zip :: [a] -> [b] -> [(a, b)]
drop 1 :: [a] -> [a]
filter :: (a -> Bool) -> [a] -> [a]
(<) :: Ord a => a -> a -> Bool
uncurry :: (a -> b -> c) -> (a, b) -> c
map :: (a -> b) -> [a] -> [b]
snd :: (a, b) -> b
Note: drop 1 can be used when you’d prefer a “safe” version of tail.
If you like over-generalization like me, you can use the witherable package.
{-# language ScopedTypeVariables #-}
import Control.Monad.State.Lazy
import Data.Witherable
{-
class (Traversable t, Filterable t) => Witherable t where
-- `wither` is an effectful version of mapMaybe.
wither :: Applicative f => (a -> f (Maybe b)) -> t a -> f (t b)
-}
greaters
:: forall t a. (Ord a, Witherable t)
=> t a -> t a
greaters xs = evalState (wither go xs) Nothing
where
go :: a -> State (Maybe a) (Maybe a)
go curr = do
st <- get
put (Just curr)
pure $ case st of
Nothing -> Nothing
Just prev ->
if curr > prev
then Just curr
else Nothing
The state is the previous element, if there is one. Everything is about as lazy as it can be. In particular:
If the container is a Haskell list, then it can be an infinite one and everything will still work. The beginning of the list can be produced without withering the rest.
If the container extends infinitely to the left (e.g., an infinite snoc list), then everything will still work. How can that be? We only need to know what was in the previous element to work out the state for the current element.
"Roll your own recursive function" is certainly an option here, but it can also be accomplished with a fold. filter can't do it because we need some sort of state being passed, but fold can nicely accumulate the result while keeping that state at the same time.
Of course the key idea is that we keep track of last element add the next one to the result set if it's greater than the last one.
greaters :: [Int] -> [Int]
greaters [] = []
greaters (h:t) = reverse . snd $ foldl (\(a, r) x -> (x, if x > a then x:r else r)) (h, []) t
I'd really love to eta-reduce it but since we're dropping the first element and seeding the accumulator with it it kinda becomes awkward with the empty list; still, this is effectively an one-liner.
So i have come up with a foldr solution. It should be similar to what #Will Ness has demonstrated but not quite i suppose as we don't need a separate empty list check in this one.
The thing is, while folding we need to encapsulate the previous element and also the state (the result) in a function type. So in the go helper function f is the state (the result) c is the current element of interest and p is the previous one (next since we are folding right). While folding from right to left we are nesting up these functions only to run it by applyying the head of the input list to it.
go :: Ord a => a -> (a -> [a]) -> (a -> [a])
go c f = \p -> let r = f c
in if c > p then c:r else r
greaters :: Ord a => [a] -> [a]
greaters = foldr go (const []) <*> head
*Main> greaters [1,3,2,4,3,4,5]
[3,4,4,5]
*Main> greaters [5,10,6,11,7,12]
[10,11,12]
*Main> greaters [651,151,1651,21,651,1231,4,1,16,135,87]
[1651,651,1231,16,135]
*Main> greaters [1]
[]
*Main> greaters []
[]
As per rightful comments of #Will Ness here is a modified slightly more general code which hopefully doesn't break suddenly when the comparison changes. Note that const [] :: b -> [a] is the initial function and [] is the terminator applied to the result of foldr. We don't need Maybe since [] can easily do the job of Nothing here.
gs :: Ord a => [a] -> [a]
gs xs = foldr go (const []) xs $ []
where
go :: Ord a => a -> ([a] -> [a]) -> ([a] -> [a])
go c f = \ps -> let r = f [c]
in case ps of
[] -> r
[p] -> if c > p then c:r else r
I want to make a mapping to an array with a function but only is a condition is fullfilled. For my particular problem I have an array of objects and only want to do a function on a sub-array of this big array.
function :: a -> a
mapping :: [a] -> [a] -> [a]
mapping all sub = map (\x -> if (x `elem` sub) then function x else x) all
how can I do something like this ?
edit: I know this code works but in my class this is considered bad design and we need to avoid using if statements and need to use guards and such instead.
The part that seems like bad design to me is that you fail to factor out the basic pattern. As assembly.jc has pointed out, you should really give that its own function.
mapOnly :: (a -> Bool) -> (a -> a) -> [a] -> [a]
mapOnly p f = map $ \x -> if p x then f x else x
Using if seems quite reasonable style in this context; anything else really comes off as clunky.
If you are force to use guards, is pretty straightforward. I think if .. then .. else is a good pattern here though. As #dfeuer says, include the predicate and the function in mapping's signature.
mapping :: (a -> Bool) -> (a -> a) -> [a] -> [a]
mapping _ _ [] = []
mapping p f (a:as)
| p a = f a: mapping p f as
| otherwise = a:mapping p f as
Haskell newb here
I'm working on this problem in haskell:
(**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
* (compress '(a a a a b c c a a d e e e e))
(A B C A D E)
The solution (which I had to look up) uses foldr:
compress' :: (Eq a) => [a] -> [a]
compress' xs = foldr (\x acc -> if x == (head acc) then acc else x:acc) [last xs] xs
This foldr, according to the solution, takes two parameters, x and acc. It would seem like all foldr's take these parameters; is there any exception to this? Like a foldr that takes 3 or more? If not, is this convention redundant and can the formula be written with less code?
foldr takes a function of 2 arguments, but this doesn't prevent it from taking a function of 3 arguments provided that function has the right type signature.
If we had a function
g :: x -> y -> z -> w
With
foldr :: (a -> b -> b) -> b -> [a] -> b
Where we want to pass g to foldr, then (a -> b -> b) ~ (x -> y -> z -> w) (where ~ is type equality). Since -> is right associative, this means we can write g's signature as
x -> y -> (z -> w)
and its meaning is the same. Now we've produced a function of two parameters that returns a function of one parameter. In order to unify this with the type a -> b -> b, we just need to line up the arguments:
a -> | x ->
b -> | y ->
b | (z -> w)
This means that b ~ z -> w, so y ~ b ~ z -> w and a ~ x so g's type really has to be
g :: x -> (z -> w) -> (z -> w)
implying
foldr g :: (z -> w) -> [x] -> (z -> w)
This is certainly not impossible, although more unlikely. Our accumulator is a function instead, and to me this begs to be demonstrated with DiffLists:
type DiffList a = [a] -> [a]
append :: a -> DiffList a -> DiffList a
append x dl = \xs -> dl xs ++ [x]
reverse' :: [a] -> [a]
reverse' xs = foldr append (const []) xs $ []
Note that foldr append (const []) xs returns a function which we apply to [] to reverse a list. In this case we've given an alias to functions of the type [a] -> [a] called DiffList, but it's really no different than having written
append :: a -> ([a] -> [a]) -> [a] -> [a]
which is a function of 3 arguments.
As with all things in haskell have a look at the types of things to guide your way you can do this for any function in ghci.
Looking at this for foldr we see:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
This slightly abstract string can be written in english as:
foldr is a function that takes
1 ) a function with two parameters one of type a and one of type b and returns something of type b
2 ) A value of type b
3 ) A list of values of type a
And returns a value of type b
Where a and b are type variables (see here for a good tutorial on them) which can be filled in with any type you like.
It turns out that you can solve your compress problem using a foldr with a three-argument function.
compress :: Eq a => [a] -> [a]
compress [] = []
compress (z:zs) = z : foldr f (const []) zs z
where f x k w | x==w = k x
| otherwise = x : k x
Let's dissect that. First, we can improve readability by changing the last two lines to
where f x k = \w -> if x==w then k x else x : k x
This makes it evident that a ternary function is nothing but a binary function returning a unary function. The advantage of looking at it in this way is that foldr is best understood when passed a binary function. Indeed, we are passing a binary function, which just happens to return a function.
Let's focus on types now:
f :: a -> (a -> [a]) -> (a -> [a])
f x k
So, x::a is the element of the list we are folding on. Function k is the result of the fold on the list tail. The result of f x k is something having the same type as k.
\w -> if .... :: (a -> [a])
The overall idea behind this anonymous function is as follows. The parameter k plays the same role as acc in the OP code, except it is a function expecting the previous element w in the list before producing the accumulated compressed list.
Concretely, we use now k x when we used acc, passing on the current element to the next step, since by that time x will become the previous element w. At the top-level, we pass z to the function which is returned by foldr f (const []).
This compress variant is lazy, unlike the posted solution. In fact, the posted solution needs to scan the whole list before starting producing something: this is due to (\x acc -> ...) being strict in acc, and to the use of last xs. Instead, the above compress outputs list elements in a "streaming" fashion. Indeed, it works with infinite lists as well:
> take 10 $ compress [1..]
[1,2,3,4,5,6,7,8,9,10]
That being said, I think using a foldr here feels a bit weird: the code above is arguably less readable than the explicit recursion.
The task: I'm attempting to write a function with type signature minimum_recursive :: (a -> a -> Bool) -> [a] -> a . For its first parameter, it accepts a function I will call less that takes two parameters, and returns True if the first param is less than the second, False otherwise. minimum_recursive also accepts a list as its second parameter. Using explicit recursion, minimum_recursive should determine the smallest value in its input list [a].
My thinking: I was thinking to put the actual recursion in a helper function that also accepts an accumulator. I would call the helper function with the first item as the accumulator.
What I have so far: So far I have the following:
-- function as first parameter to min'
-- accepts two params, returns True if
-- first must come before second in sorted
-- order
less :: Ord a => a -> a -> Bool
less a b = a < b
-- Subpart B
minimum_recursive :: (a -> a -> Bool) -> [a] -> a
minimum_recursive func list = minimum_recursive_h func list []
I am having trouble figuring out how to even begin to write minimum_recursive_h.
Note: I know there probably is an easier way to accomplish this task, but I'm required to go about it as specified above.
You could do it like this:
minimum_recursive _ [] = error "no minimum of empty list"
minimum_recursive _ [x] = x
minimum_recursive f (x:xs) = let m = minimum_recursive f xs
in if f x m then x else m
Or, with an accumulator:
minimum_recursive _ [] = error "no minimum of empty list"
minimum_recursive f (x:xs) = helper f x xs
where
helper _ m [] = m
helper f m (x:xs)
| f m x = helper f m xs
| otherwise = helper f x xs
If you want the smallest ellement in the list I sugest that you add the smallest ellement you currently have as a parameter to the function.
minimum_recursive :: (a -> a -> Bool) -> a -> [a] -> a
minimum_recursive f min [] = min
minimum_recursive f min (x:xs) | f min x = minimum_recursive f min xs
| otherwise = minimum_recursive f x xs
You should also change the type in the function that call this from a to Maybe a since there are no smallest ellement in an empty list. Here some help about Maybe
If you want to do it without an extra parameter you could store the smallest ellement in the beginning of the list ass well. In this case it's important to use Maybe
minimum_recursive :: (a -> a -> Bool) -> [a] ->Maybe a
minimum_recursive f [] = Nothing
minimum_recursive f (x:[]) = Just x
minimum_recursive f (y:(x:xs)) | f y x = minimum_recursive f (y:xs)
| otherwise = minimum_recursive f (x:xs)
This is how the minumum can be found ehit fold. Look at the beauty of functionall programming. But this wont work for the empty list
simplefold :: [a] -> a
simplefold (x:xs) = foldl min x xs
But we can embed this function in one that checks if the list is empty and return Nothing in that case.
betterfold :: [a] -> Maybe a
betterfold [] = Nothing
beterfold l = Just (simplefold l)
The classic way to solve problems recursively is the following:
Assume you've nearly solved the problem, except for the final step.
Write the code that, given the solution for all except that final step, computes the solution produced by that final step.
Write the base case.
In the case of lists, this translates to this pattern:
Base case: what should the solution be for []? (if anything; in the case of your minimum_recursive function, this would be an error).
For a nonempty list x:xs, assume you already have almostTheResult = minimum_recursive f xs. How do you compute minimum_recursive (x:xs) given that?
I'll give you a big hint: your minimum_recursive can be implemented in terms of foldr and this function:
minBy :: (a -> a -> Bool) -> a -> a -> a
minBy pred x y = if pred x y then x else y
The foldr function does exactly what I'm describing above. The first argument to foldr is the function that computes the final solution given the list head and the partial solution for the tail, and the second argument is the result base case.