HW: Unfolding a list in a specific way
functional-programming, haskell, unfold
Solution
You've almost got it! The original function uses the function `p` (for 'predicate') to determine whether we've finished unfolding, `h` to apply to each element, and `t` (for 'transformation') to transform an element into the seed for the rest of the list.
`unfoldr` expects a single function `f :: b -> Maybe (a,b)`, which returns `Nothing` if we've finished unfolding, or `Just (x, y)`, where `x` is the element to add to the list and `y` is the seed for the rest of the list.
So `f` in `unfoldr` is responsible for the functionality of all three of `p`, `h` and `t`. The `Nothing`-or-`Just` dichotomy plays the part of the Boolean function `p`, and the second element of the tuple does `t`'s job of supplying the seed for the rest of the list.
Here's my solution (I've renamed the variables from your question, for clarity):
listUnfold pred f trans seed =
unfoldr (\x -> if pred x
then Nothing
else Just (f x, trans x)) seed
Of course, when a value appears on the right-hand-end of a definition, as `seed` does here, you can take advantage of Haskell's sexy syntax for currying and throw it away altogether:
listUnfold pred f trans = unfoldr (\x -> if pred x
then Nothing
else Just (f x, trans x))
Formally, this transformation is known as eta reduction.
Problem
In Programming in Haskell, Graham Hutton defines an unfold for lists as follows: ``` unfold :: (b -> Bool ) -> (b -> a) -> (b -> b) -> b -> [a] unfold p h t x | p x = [] | otherwise = h x : unfold p h t (t x) ``` Define a function ``` • listUnfold :: (b -> Bool) -> (b -> a) -> (b -> b) -> b -> [a] ``` that is similar to the one above but uses unfoldr in its implementation and is non-recursive. I've been trying for a while to solve the question above but I still can manage to do so (pretty new in Haskell and functional programming in general). My attempt: ``` listUnfold :: (b -> Bool) -> (b -> a) -> (b -> b) -> b -> [a] listUnfold f h t x | f x == True = [] | otherwise = h x : listUnfoldr (\x -> if f x then Nothing else Just ((h x), (t x))) x ``` In english, if `f x` is true, return the empty list. Otherwise, use `h x` as the head and append the results of unfoldr as the tail. Unfoldr takes a list `(x:xs)` should recurse itself with `x` as the head and `xs` as the tail. p/s: I'm probably doing this very very wrongly.