I am giving my self exercises and wondering if there is a way to find the first item from left in the list matching a certain criteria using just foldr? I want the recursion to stop when the first item is found (I know I could probably combine using take) but I am curious to know if it is possible to do just using foldr?
firstFind (\x -> x > 1000) [] xs
The problem: find f and b.
firstFind :: (a -> Bool) -> [a] -> Maybe a
firstFind p list = foldr f b list
where f = ???
b = ???
We want:
firstFind p [] = Nothing
but we also have
firstFind p []
= def. firstFind
foldr f b []
= def. foldr
b
from which we see what b must be.
Further, take list = x:xs
firstFind p list
= def. firstFind
foldr f b (x:xs)
= def. foldr
f x (foldr f b xs)
= def. firstFind
f x (firstFind p xs)
Now, we just need to find f so that this chooses the first match.
Recall that f can depend on p. What should f return when p x is true? What in the opposite case?
where -- f :: a -> Maybe a -> Maybe a
f x y = ???
(Note: above I wrote the type signature for f for clarity, but you don't have to include it in your code. If you add it, uncommented, you will trip into a type variable confusion: that a is not the same a as in findFirst because it is generalized locally -- since you are just beginning, ignore this and simply remove it for the moment being.)
Related
So, there is something known as a "universal property of fold", stating exactly following:
g [] = i; g (x:xs) = f x (g xs) <=> g = fold f i
However, as you probably now, there are rare cases like dropWhile, which can not be redefined as fold f i unless you generalize it.
The simplest yet obvious way to generalize is to redefine universal property:
g' y [] = j y; g' y (x:xs) = h y x xs (g' y xs) <=> g' y = fold (?) l
At this point I can make my assumption: I assume existence of somewhat function p :: a -> b -> b, which would satisfy the equation g' y = fold p l. Let's try to solve given equation with help of universal property, mention at the very beginning:
g' y [] = j y = fold p l [] = l => j y = l
g' y (x:xs) = h y x xs (g' y xs) = fold p l (x:xs) = p x (fold p l xs) = p x (g' y xs) => letting rs = (g' y xs), h y x xs rs = p x rs, which is wrong: xs occurs freely from the left and thus equality can't hold.
Now let me try to interpret result I've came up with and ask question.
I see that the problem is xs emerging as unbound variable; it's true for various situations, including above mentioned dropWhile. Does it mean that the only way that equation can be solved is by "extending" rs to a pair of (rs, xs)? In other words, fold accumulates into tuple rather than a single type (ignoring the fact that tuple itself is a single type)? Is there any other way to generalize bypassing pairing?
It is as you say. The universal property says that g [] = i; g (x:xs) = f x (g xs) iff g = fold f i. This can't apply for a straightforward definition of dropWhile, as the would-be f :: a -> [a] -> [a] depends not just on the element and accumulated value at the current fold step, but also on the whole list suffix left to process (in your words, "xs emerg[es] as an unbound variable"). What can be done is twisting dropWhileso that this dependency on the list suffix becomes manifest in the accumulated value, be it through a tuple -- cf. dropWhilePair from this question, with f :: a -> ([a], [a]) -> ([a], [a]) -- or a function -- as in chi's implementation...
dropWhileFun = foldr (\x k -> \p -> if p x then k p else x : k (const False)) (const [])
... with f :: a -> ((a -> Bool) -> [a]) -> ((a -> Bool) -> [a]).
At the end of the day, the universal property is what it is -- a fundamental fact about foldr. It is no accident that not all recursive functions are immediately expressible through foldr. In fact, the tupling workaround your question brings to the table directly reflects the notion of paramorphism (for an explanation of them, see What are paramorphisms? and its exquisite answer by Conor McBride). At face value, paramorphisms are generalisations of catamorphisms (i.e. a straightforward fold); however, it only takes a slight contortion to implement paramorphisms in terms of catamorphisms. (Additional technical commentary on that might be found, for instance, in Chapter 3 of Categorical Programming With Inductive and Coinductive Types, Varmo Vene's PhD thesis.)
I have a list
let a = [1,2,3,4]
I want to extract 2 elements at a time to perform computation. Can anyone tell me how this can be achieved? I am new to Haskell.
I am aware of take 2 a. But how can I put this in a loop so that 2 elements are extracted at a time. I am confused.
Here's an example. You are (or should become) familiar with the map function:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
Here, you might have a function that takes two arguments, and want to apply it to two elements from a list at a time. Here's a function mapTwo that behaves like map, but with a two-argument function. For simplicity, we'll assume the list has an even number of elements.
mapTwo :: (a -> a -> b) -> [a] -> [b]
mapTwo f [] = []
mapTwo f (x1:x2:xs) = f x1 x2 : mapTwo f xs
You can write your own recursive function and pattern-match on elements you are interested in:
f (a:b:list) = doSomeThingWith a b : f list
Make sure to properly match on [] and [a] cases.
my title might be a bit off and i'll try to explain a bit better what i'm trying to achieve.
Basically let's say i have a list:
["1234x4","253x4",2839",2845"]
Now i'd like to add all the positions of the strings which contain element 5 to a new list. On a current example the result list would be:
[1,3]
For that i've done similar function for elem:
myElem [] _ = False
myElem [x] number =
if (firstCheck x) then if digitToInt(x) == number then True else False else False
myElem (x:xs) number =
if (firstCheck x) then (if digitToInt(x) == number then True else myElem xs number) else myElem xs number
where firstCheck x checks that the checked element isn't 'x' or '#'
Now in my current function i get the first element position which contains the element, however my head is stuck around on how to get the full list:
findBlock (x:xs) number arv =
if myElem x number then arv else findBlock xs number arv+1
Where arv is 0 and number is the number i'm looking for.
For example on input:
findBlock ["1234x4","253x4",2839",2845"] 5 0
The result would be 1
Any help would be appreciated.
The function you want already exists in the Data.List module, by the name of findIndices. You can simply use (elem '5') as the predicate.
http://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#v:findIndices
If, for some reason, you're not allowed to use the built-in one, it comes with a very pretty definition (although the one actually used has a more complicated, more efficient one):
findIndices p xs = [ i | (x,i) <- zip xs [0..], p x]
By the way, I found this function by searching Hoogle for the type [a] -> (a -> Bool) -> [Int], which (modulo parameter ordering) is obviously the type such a function must have. The best way to find out of Haskell has something is to think about the type it would need to have and search Hoogle or Hayoo for the type. Hoogle is better IMO because it does slightly fuzzy matching on the type; e.g. Hayoo wouldn't find the function here by the type I've given, because it take the arguments in the reverse order.
An implementation of findIndices, for instructional purposes:
findIndices ok list = f list 0 where
f [] _ = []
f (x:xs) ix
| ok x = ix : f xs (ix+1)
| otherwise = f xs (ix+1)
Use it like findIndices (elem '5') my_list_o_strings
You're trying to work your way through a list, keeping track of where you are in the list. The simplest function for doing this is
mapWithIndex :: (Int -> a -> b) -> [a] -> [b]
mapWithIndex = mwi 0 where
mwi i _f [] = i `seq` []
mwi i f (x:xs) = i `seq` f i x : mwi (i+1) f xs
This takes a function and a list, and applies the function to each index and element. So
mapWithIndex (\i x -> (i, x)) ['a', 'b', 'c'] =
[(0,'a'), (1,'b'),(2,'c')]
Once you've done that, you can filter the list to get just the pairs you want:
filter (elem '5' . snd)
and then map fst over it to get the list of indices.
A more integrated approach is to use foldrWithIndex.
foldrWithIndex :: (Int -> a -> b -> b) -> b -> [a] -> b
foldrWithIndex = fis 0 where
fis i _c n [] = i `seq` n
fis i c n (x:xs) = i `seq` c i x (fis (i+1) c n xs)
This lets you do everything in one step.
It turns out that you can implement foldrWithIndex using foldr pretty neatly, which makes it available for any Foldable container:
foldrWithIndex :: (Foldable f, Integral i) =>
(i -> a -> b -> b) -> b -> f a -> b
foldrWithIndex c n xs = foldr go (`seq` n) xs 0 where
go x r i = i `seq` c i x (r (i + 1))
Anyway,
findIndices p = foldrWithIndex go [] where
go i x r | p x = i : r
| otherwise = r
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Library function to compose a function with itself n times
I need a function to call another function n number of times.
so it would look something like this
f n = g(g(g(g(l))))
where n equals to the number of function g nested.
how should I go about this? thanks!
iterate is a common solution:
> :t iterate
iterate :: (a -> a) -> a -> [a]
So, given a function with a domain the same as its range, a -> a, and an initial input a, produce an infinite list of results in the form:
iterate f a --> [a, f(a), f(f(a)), ...]
And you can access the nth element of the list using !!:
iterate f a !! n
NB iterate f a !! 0 == a.
This is a function that I use often at the ghci prompt. There are a few ways to write it, none of which I am particularly fond of, but they are all reasonably clean:
fpow n f x = iterate f x !! n
fpow n f = foldr (.) id $ replicate n f
fpow n = foldr (.) id . replicate n -- just eta the above
fpow 0 f = id
fpow n f = f . fpow (n-1) f
The middle two appeal to me because my brain has chunked foldr (.) id to mean "compose a list of functions".
I kinda just wish it were in the prelude :-).
f 0 = l
f n = g (f (n-1))
But more functional would be:
f 0 l = l
f n l = g (f (n-1) l)
This could also be done with folds or morfisms, but this is easier to understand.
For example here's using a hylomorphism, but it doesn't make it clearer really:
f g l = hylo l (.) (\n -> (g, n-1)) (==0)
It says some thing like compose (.) g(l) until n==0
Can be done using fold:
applyNTimes :: Int -> (a -> a) -> a -> a
applyNTimes n f val = foldl (\s e -> e s) val [f | x <- [1..n]]