How to concatenate a value to a list when both are inside Maybes? - haskell

I'm reading realworldhaskell and I've come to chapter 4 where the book talks about "Safely and sanely working with crashy functions". I'm trying to write a safe version of init :: [a] -> [a]. This is as far as I got:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) = ???
I get that I can't do something like x : mySafeInit xs, because that would be like doing a : Just [a] (right?). I've read about fmap though, so I tried this:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) = fmap (:) (Just x) (mySafeInit xs)
Well that's guaranteed to work, right? Well no, and I'm struggling to understand why. Here I have a Just a and a Just [a], right? Shouldn't I be able to use fmap, give it the function (:) and my two maybes, and get a Just [a] back?
After some googling I did figure out that this works:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) = fmap (:) (Just x) <*> (mySafeInit xs)
but I don't understand why. Could someone walk me through this? :)

Let's look at
fmap (:) (Just x) (mySafeInit xs)
For Maybe, fmap is defined as
fmap _ Nothing = Nothing
fmap f (Just x) = Just (f x)
Therefore
fmap (:) (Just x)
is
Just ((:) x)
Note that this is not a function; it's a Maybe value of some type (in fact, it's Maybe ([a] -> [a])). That's why
(Just ((:) x)) (mySafeInit xs)
is a type error (you can only apply functions).
In the second version of your code, you did
fmap (:) (Just x) <*> (mySafeInit xs)
, which is
(Just ((:) x)) <*> (mySafeInit xs)
Looking at the type of <*>, we get:
(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
Here f is Maybe, and a and b are both [a]:
(<*>) :: Maybe ([a] -> [a]) -> Maybe [a] -> Maybe [a]
That's why this version checks out.
Shouldn't I be able to use fmap, give it the function (:) and my two maybes, and get a Just [a] back?
No, because fmap only works with functions of one argument. There is another function for two arguments, though:
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
Contrast with
fmap :: (Functor f) => (a -> b) -> f a -> f b
liftA2 (:) (Just x) (mySafeInit xs) should indeed work.
But it's needlessly complicated because one of your maybes is artificial: You explicitly wrapped your x in Just. You can simply do this instead:
fmap ((:) x) (mySafeInit xs)
By the definition of fmap, this is either Nothing (if mySafeInit xs is Nothing) or Just ((:) x y) (if mySafeInit xs is Just y).

Simple solution
I think you make things too hard/complex. You can simply consider two cases:
the empty list, in which case you return a Nothing; and
the non-empty list, in which case you can use the old init:
Or putting it into code:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit l = Just (init l)
Now of course we have to trust that there are only two constructors for a list; and that init will only error when we provide it an empty list. Both assumptions hold, but can (although very unlikely) change in the future.
We can however use our own init function:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (l:ls) = Just (init l ls)
where init _ [] = []
init x (x2:xs) = x : init x2 xs
Now the Haskell compiler can verify that both functions are syntactically total. Note that functions can be total, but not syntactically: for instance because we can make assumptions regarding the structure of the data that the compiler can not check.
Working with fmap
You provide a solution like:
-- ...
mySafeInit (x:xs) = fmap (:) (Just x) <*> (mySafeInit xs)
A first aspect we have to understand is that Maybe is a Functor. A Fuctor supports a function fmap where we map the item(s) inside the functor so to speak. For instance a list is a functor as well, and we can thus map all elements in the list with fmap f somelist. You can see Maybe as some sort of list with zero elements (the Nothing) or one element (the Just x). So in case we perform fmap on a Nothing, we get a Nothing back, in case we perform this on a Just x, we get Just (f x).
Here we see fmap (:) (Just x). Since we thus apply it on a Just x, we have actually constructed:
fmap (:) Just x
-> Just ((x :))
This is thus a Just, but it carries a function (x : ), not a value.
Next we see a <*> operator. (<*>) :: Applicative f => f (a -> b) -> f a -> f b is some sort of "multiplication" over an Applicative (a Maybe is an applicative as well). On the left side we have an applicative of functions a -> b, on the right side an applicative of as. The result is an applicative of bs: for every tuple of functions and values.
In case we perform this on a list, we thus obtain a list that starts with the values all applied to the first function, then all values applied to the second function, etc.
For a Maybe we thus have a Maybe (a -> b) left and a Maybe a on the right. In case these are of the form Just f and Just x, we obtain Just (f x), in all other cases we obtain Nothing.
Since we perform a recursive call on mySafeInit xs, we thus obtain the init of the remaining list wrapped in a Just. In that case, we thus prepend that result with xs.
An equivalent code definition is thus:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) | Just ys <- mySafeInit xs = Just (x:ys)
| otherwise = Nothing

Related

Can this function be written in point-free style? If not, why?

One related question is this, but some of the answer say that almost anything can be made point free, so what is wrong with this function?
\[x] -> x
http://pointfree.io/ doesn't seem to be able to write it in point-free style. Does this mean that it cannot be written that way? If so, what is the theoretical reason for it?
I can only observe that the function above is a "crippled" version of head (or last, fwiw) which can only operate on singleton lists. Indeed, applied on non singleton lists, it errors this way in ghci:
*** Exception: <interactive>:380:5-13: Non-exhaustive patterns in lambda
Maybe the "non-exhaustivity" on the pattern is the reason why some functions cannot be written in point-free style?
Edit in the light of the answers:
I did not expect that the answers to my question could be so complex (I feel I just thought that the short answer was no, it cannot, actually), so I need to find some time to read them carefully, experiment a bit, and wrap my mind around them, otherwise I cannot decide which one should be accepted. For the time being, +1 to Jon Purdy's answer, which I could easily understand up to This is where I would stop in ordinary code.
Well, a data type isn't a function. As long as your function isn't unwrapping any data values (i.e. it's just shuffling them between functions/constructors), you can write it point free, but there's simply no syntax for point free matching. However, you only ever need one non-point-free function per data type: the fold. In Haskell, data types are pretty much defined by their folds. Taking the folds of the relevant data types as primitives, you can rewrite any function point free. Note that there are actually several possible "folds". For [a], the recursive one (which comes from the Church/Böhm-Berarducci encoding) is foldr :: (a -> b -> b) -> b -> [a] -> b. Another possible fold is the "case-but-it's-a-function" one, (a -> [a] -> b) -> b -> [a] -> b, which comes from the Scott encoding (recursion can then be recovered with fix, which is another "pointful pointfree primitive"), but, as #SilvioMayolo notes, there isn't such a function in the standard library. Either would do, but we don't have the latter predefined so let's just use foldr.
\[x] -> x
can be written
fst . foldr (\x f -> (snd f x, \_ -> error "got (_ : _ : _) wanted [x]")) (error "got [] wanted [x]", id)
-- I don't care enough to replicate the exact exceptions.
-- this is "flattened" from
let fold [] = (error "got [] wanted [x]", id)
fold (x : xs) = (snd (fold xs) x, \_ -> error "got (_ : _ : _) wanted [x]")
in fst . fold
fold returns a pair, basically (what to return if this was the entire list, how to transform the head if it wasn't). For [], we want to return an error if that was the entire list, but otherwise pass through the element right before we hit []. For x : xs, if there is an element preceding it, we want to ignore it and return an error, and if there isn't, we want to pass it to snd (fold xs), which checks if xs = [] or else gives an error. We've eliminated all matches, so just shove this through pointfree.io to get the \x f -> _ in the argument to foldr out:
behead = fst . foldr (flip flip (const (error "got (_ : _ : _) wanted [x]")) . ((,) .) . flip snd) (error "got [] wanted [x]", id)
ghci> :t behead
behead :: Foldable t => t c -> c
ghci> behead []
*** Exception: got [] wanted [x]
ghci> behead [1]
1
ghci> behead [1, 2]
*** Exception: got (_ : _ : _) wanted [x]
ghci> behead [1..]
*** Exception: got (_ : _ : _) wanted [x]
Lovely.
Note: a previous version of this answer used an "inlined" auxiliary data type, basically because it just "came to me" as I was writing it. However, it failed to handle infinite lists properly (behead [1..] would hang). This version uses the built in pairs as the auxiliary data type, which have sufficient library support that I don't have to inline them to make it pointfree. It is slightly harder to inline (,), thereby eliminating the pointfullness inside the implementations of fst and snd, but it is still possible, using this newtype:
newtype Pair a b = Pair { unPair :: forall r. (a -> b -> r) -> r }
Alternatively, cheat on the types a bit and use this:
-- residual pointfullness can be reduced by pointfree.io
\xs -> foldr (\x r f -> f (r (const id) x) (\_ -> error "got (_ : _ : _) wanted [x]")) (\f -> f (error "got [] wanted [x]") id) xs (\x _ _ -> x) undefined
Sure, pretty much anything can be made pointfree. The tricky thing is what functions you'll allow in the resulting expression. If we pattern match, we generally need a fold function to do the matching instead. So, for instance, if we pattern matched on a Maybe a, we'd need to replace that with maybe. Similarly, Either a b patterns can be written in terms of either.
Note the pattern in the signatures
data Maybe a = Nothing | Just a
maybe :: b -> (a -> b) -> (Maybe a -> b)
Maybe a has two constructors, one which takes no arguments and the other which takes an a. So maybe takes two arguments: one which is a 0-ary function (b), and one which takes an a (a -> b), and then returns a function from Maybe a -> b. The same pattern is present in either
data Either a b = Left a | Right b
either :: (a -> c) -> (b -> c) -> (Either a b -> c)
Two cases. The first takes an a and produces whatever c we want. The second takes a b and produces whatever c we want. In every case, we want one function for each possible term in the sum type.
In order to systematically pointfree a function like \[x] -> x, we'd need a similar fold. [a] is declared as, essentially
data [a] = [] | a : [a]
So we'd need a function with this signature
list :: b -> (a -> [a] -> b) -> ([a] -> b)
Now, flip foldr comes close
flip foldr :: b -> (a -> b -> b) -> ([a] -> b)
But it's recursive. It calls its provided function on the [a] part of a : [a]. We want a true fold, which isn't provided by Haskell's base libraries. A quick Hoogle search tells us that this function does exist in a package though, called extra. Of course, for this small example we can just write it ourselves very easily.
list :: b -> (a -> [a] -> b) -> ([a] -> b)
list f g x = case x of
[] -> f
(y:ys) -> g y ys
Now we can apply it to your \[x] -> x easily. First, let's write what your function really does, including all of the messy undefined cases (I'll use undefined rather than a long error message here, for brevity)
func :: [a] -> a
func x = case x of
[] -> undefined
(y:ys) -> case ys of
[] -> y
(_:_) -> undefined
Now every case statement exactly matches each constructor once. This is ripe for transformation into a fold.
func :: [a] -> a
func x = case x of
[] -> undefined
(y:ys) -> list y undefined ys
And now we transform the outer case as well
func :: [a] -> a
func x = list undefined (\y -> list y undefined) x
So we have
func :: [a] -> a
func = list undefined (\y -> list y undefined)
Or, if we want to be truly crazy about it
func :: [a] -> a
func = list undefined (flip list undefined)
But this function isn't in base
Yeah, that's true. We kind of cheated by using a fold that didn't exist. If we want to do it systematically, we need that fold operator. But without it, we can still kludge it together with foldr1, which suffices for our particular purposes.
func' :: [a] -> a
func' = foldr1 (const (const undefined))
So, to answer your question, we can't always systematically replace pattern matching like in your example with pointfree, unless we have a fold function with the right signature. Fortunately, that function can always be written, for any Haskell 98 data type (possibly GADTs as well, but I haven't considered that possibility in any depth). But even without that support, we can still make it work, kind of.
A simple way to write this in pointfree form is to use a fold, where the accumulator state is one of the following:
Empty: We haven’t seen an element yet; keep it
Full: We have seen an element; raise an error
If the final state is Empty, we also raise an error. This accumulator can be represented naturally with Maybe:
fromSingleton :: (Foldable t) => t a -> a
fromSingleton
= fromMaybe (error "empty list")
. foldr (flip maybe (error "plural list") . Just) Nothing
This is where I would stop in ordinary code. But…
If you don’t want to use an auxiliary data type, you can get rid of the Maybe by representing it with Böhm–Berarducci encoding:
type Maybe' r a
= r -- ‘Nothing’ continuation
-> (a -> r) -- ‘Just’ continuation
-> r -- Result
just' :: a -> Maybe' r a
-- just' = \ x _n j -> j x
just'
= const -- Ignore ‘Nothing’ continuation
. flip ($) -- Apply ‘Just’ continuation to value
nothing' :: Maybe' r a
-- nothing' = \ n _j -> n
nothing' = const -- Ignore ‘Just’ continuation
maybe' :: r -> (a -> r) -> Maybe' r a -> r
-- maybe' = \ n j k -> k n j
maybe'
= flip -- Apply to ‘Just’ continuation
. flip ($) -- Apply to ‘Nothing’ continuation
fromMaybe' :: r -> Maybe' r r -> r
-- fromMaybe' = \ n k -> k n id
fromMaybe' = flip maybe' id -- Pass ‘id’ as ‘Just’ continuation
However, we can’t just do a wholesale replacement of Just with just', maybe with maybe', and so on; the types won’t work out:
> :t fromMaybe' (error "empty list") . foldr (flip maybe' (error "plural list") . just') nothing'
<interactive>:…:…: error:
• Occurs check: cannot construct the infinite type: c ~ Maybe' c c
Expected type: c -> Maybe' c c -> Maybe' c c
Actual type: c -> Maybe' (Maybe' c c) c -> Maybe' c c
• In the first argument of ‘foldr’, namely
‘(flip maybe' (error "plural list") . just')’
In the second argument of ‘(.)’, namely
‘foldr (flip maybe' (error "plural list") . just') nothing'’
In the expression:
fromMaybe' (error "empty list")
. foldr (flip maybe' (error "plural list") . just') nothing'
The problem is that we’re returning a Maybe' from a Maybe' continuation, and the compiler is trying to unify the two result types. One solution is to first eta-expand to let the typechecker know where we want to construct a distinct function:
> :t fromMaybe' (error "empty list") . foldr (\ x acc -> \ n j -> maybe' (just' x n j) (error "plural list") acc) nothing'
fromMaybe' (error "empty list") . foldr (\ x acc -> \ n j -> maybe' (just' x n j) (error "plural list") acc) nothing'
:: Foldable t => t c -> c
Then we can incrementally rewrite to pointfree form:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(\ x acc
-> \ n j
-> maybe'
(just' x n j)
(error "plural list")
acc)
nothing'
-- Move ‘n’ & ‘j’ past ‘error …’ with ‘flip’:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(\ x acc
-> \ n j
-> flip maybe'
----
(error "plural list")
(just' x n j)
acc)
nothing'
-- Move ‘n’ & ‘j’ past ‘acc’ with ‘flip’ again:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(\ x acc
-> \ n j
-> flip (flip maybe' (error "plural list")) acc
----
(just' x n j))
nothing'
-- Eta-reduce ‘j’ with composition:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(\ x acc
-> \ n
-> flip (flip maybe' (error "plural list")) acc
. just' x n)
--
nothing'
-- Eta-reduce ‘n’ with ‘fmap’ (to map “under” an argument):
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(\ x acc
-> fmap (flip (flip maybe' (error "plural list")) acc)
----
. just' x)
nothing'
-- Move ‘x’ rightward with ‘flip’ on the outside:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(flip (\ acc x
----
-> fmap (flip (flip maybe' (error "plural list")) acc)
. just' x))
nothing'
-- Replace composition with ‘fmap’:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(flip (\ acc x
-> fmap (fmap (flip (flip maybe' (error "plural list")) acc))
----
(just' x)))
nothing'
-- Eta-reduce ‘x’ with composition:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(flip (\ acc
-> fmap (fmap (flip (flip maybe' (error "plural list")) acc))
. just'))
--
nothing'
-- Replace composition with ‘fmap’:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(flip (\ acc
-> fmap (fmap (fmap (flip (flip maybe' (error "plural list")) acc)))
----
just'))
nothing'
-- Move ‘acc’ rightward with ‘flip’:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(flip (\ acc
-> flip fmap just'
----
(fmap (fmap (flip (flip maybe' (error "plural list")) acc)))))
nothing'
-- Eta-reduce with composition:
fromSingleton
= fromMaybe' (error "empty list")
. foldr
(flip
(flip fmap just'
. fmap . fmap . flip (flip maybe' (error "plural list"))))
-- - -
nothing'
This is fully pointfree as well (far less readable than our original code, but better than what pointfree generates). In fact it’s good practice in pointfree code to use many small auxiliary definitions like fromMaybe' instead of inlining everything, but we can proceed to inline their definitions.
However, you can’t inline them naïvely and get exactly the same type—if you do, you’ll arrive at (Foldable t) => t (a -> b) -> a -> b. It could be a good exercise to work through where you need to eta-expand and rewrite in order to obtain the expected type, (Foldable t) => t a -> a.

Can my implementation of filter be improved?

An exercise in Haskell from First Principles says to implement filter using foldr and this is what I came up with but it feels and looks clunky. Is there a more natural way to implement it with a foldr?
import Data.Bool
myFilter :: (a -> Bool) -> [a] -> [a]
myFilter f = foldr (\x -> bool (++ []) ((:) x) (f x)) []
I would only use bool if it let me get rid of the lambda expression simply, by composing a call to bool with the predicate p: bool iffalse iftrue . p. However, p isn't the only function that needs to be called on a list element; (:) does as well. You could use the Applicative instance for functions, to write
myfilter p = foldr (bool id . (:) <*> p) [] -- yuck
but in this case I would just use a plain if expression, inside the lambda expression:
myfilter p = foldr (\x -> if p x then (x:) else id) [] -- much clearer!
Note that when specialized to functions, the Applicative's (<*>) operator is defined as f <*> g = \x -> f x (g x). I leave it as an exercise to use that definition to transform bool id . (:) <*> p into
\x -> bool id (x:) (p x).
You can use the Applicative instance of (->) a to make the lambda cleaner. But, if you want to use foldr, I don't think there's any substantial change you can effect:
myFilter f = foldr (bool id <$> (:) <*> f) []
bool id <$> (:) <*> f means \x -> bool id ((:) x) (f x). bool id has type ([a] -> [a]) -> Bool -> ([a] -> [a]). (:) has type a -> [a] -> [a], and f has type a -> Bool. When (<$>) and (<*>) are used in this way, you can think of it as pretending that (:) and f don't have an a argument, making them [a] -> [a] and Bool, respectively, applying them to bool id to get a [a] -> [a], and then ending the lie by reintroducing the a argument, making a a -> [a] -> [a]. The operators are in charge of threading that a around, so you don't need a lambda abstraction.
Rather than merely searching for a more elegant implementation, it would might help you more to learn an elegant process of searching for an implementation. This should make it simpler to find elegant solutions.
For any function h on lists we have that,
h = foldr f e
if and only if
h [] = e
h (x:xs) = f x (h xs)
In this case your h is filter p for some boolean function p that selects which elements to keep. Implementing filter p as a "simple" recursive function is not too hard.
filter p [] = []
filter p (x:xs) = if p x then x : (filter p xs) else (filter p xs)
The 1st line implies e = []. The 2nd line needs to be written in the form f x (filter p xs) to match the equation of h above, in order for us to deduce which f to plug in the foldr. To do that we just abstract over those two expressions.
filter p [] = []
filter p (x:xs) = (\x ys -> if p x then x : ys else ys) x (filter p xs)
So we have found that,
e = []
f x ys = if p x then x: ys else ys
It therefore follows,
filter p = foldr (\y ys -> if p y then y : ys else ys) []
To learn more about this method of working with foldr I recommend reading
"A tutorial on the universality and expressiveness of fold" by Graham Hutton.
Some added notes:
In case this seems overly complicated, note that while the principles above can be used in this "semi rigorous" fashion via algebraic manipulation, they can and should also be used to guide your intuition and aid you in informal development.
The equation for h (x:xs) = f x (h xs) sheds some clarity on how to find f. In the case where h is the filtering function you want an f which combines the element x with a tail that has already been filtered. If you really understand this it should be easy to arrive at,
f x ys = if p x then x : ys else ys
Yes, there is:
myFilter :: (a -> Bool) -> [a] -> [a]
myFilter f = foldMap (\x -> [x | f x])
> myFilter even [1..10]
[2,4,6,8,10]
See, I switched it on you, with foldMap.
Well, with foldr it is foldr (\x -> ([x | f x] ++)) [].

How to write my version of unfoldr in a better / more idiomatic manner in Haskell?

I'm trying to write my version of unfoldr in order to solve a chapter exercise from Haskell Book (Chapter 12, Signaling Adversity). The book says:
Write the function myUnfoldr using direct recursion. Compare with
the built-in unfoldr to check your implementation. Again, don’t look
at implementations of unfoldr so that you figure it out yourself.
And gives the following:
myUnfoldr :: (b -> Maybe (a, b)) -> b -> [a]
myUnfoldr = undefined
My initial attempt for myUnfoldr has been to write it using a single helper function:
maybeToList :: Maybe a -> [a]
maybeToList (Just x) = [x]
maybeToList Nothing = []
myUnfoldr :: (b -> Maybe (a, b)) -> b -> [a]
myUnfoldr f x = (fst $ head $ maybeToList (f x)) :
myUnfoldr f (snd $ head $ maybeToList (f x))
This type checks, and for a few example runs it seems like I've achieved what unfoldr does, because:
λ> take 10 $ unfoldr (\x -> Just (x, x + 1)) 0
[0,1,2,3,4,5,6,7,8,9]
and the same result with myUnfoldr:
λ> take 10 $ myUnfoldr (\x -> Just (x, x + 1)) 0
[0,1,2,3,4,5,6,7,8,9]
But of course, myUnfoldr is problematic because if I try the following:
λ> take 10 $ myUnfoldr (\x -> Nothing) 0
[*** Exception: Prelude.head: empty list
whereas unfoldr works as expected, returning [].
I can see why my unFoldr is problematic, but I couldn't find out how to handle the situation where f can return Nothing.
So my second take at the problem is to use another helper function, and this time use guards:
isJust :: Maybe a -> Bool
isJust (Just _) = True
isJust _ = False
myUnfoldr :: (b -> Maybe (a, b)) -> b -> [a]
myUnfoldr f x | isJust $ (f x) = (fst $ head $ maybeToList (f x)) : myUnfoldr f (snd $ head $ maybeToList (f x))
| otherwise = []
This second version seems to work as expected both for take 10 $ myUnfoldr (\x -> Just (x, x+1)) 0 and take 10 $ myUnfoldr (\x -> Nothing) 0
But I'm still not comfortable with my solution.
Any ideas whether it can be written in a more concise form, without using a helper function? Or in a more idiomatic way?
Two words: pattern matching. You're using $ head $ maybeToList (f x) twice to get both the next state as well as the list element. However, we can pattern match on f x to get whether we're having Just another element (and a state to continue our little unfolding) or whether we're done:
myUnfoldr :: (s -> Maybe (a, s)) -> s -> [a]
myUnfoldr f x = case f x of
Just (next, state) -> next : myUnfoldr f state
Nothing -> []
The problem with your variant is that you don't use isJust (f x) to your advantage. Instead of checking whether something is Just and then getting the values out of it, just check whether the pattern matches.
Note that this is also possible with pattern guards:
myUnfoldr :: (s -> Maybe (a, s)) -> s -> [a]
myUnfoldr f x
| Just (next, state) <- f x = next : myUnfoldr f state
| otherwise = []
I haven't read the book yet, but I guess that both techniques have been told by chapter 12.

How to implement the head function using fst function

I admit this is my homework. But I really couldn't find a good solution after working hard on it.
There might be some stupid ways to accomplish this, like:
myHead (x:[]) = x
myHead (x:y:xs) = fst (x, y)
But I don't think that's what the teacher wants.
BTW, error-handling is not required.
Thanks in advance!
There's a very natural function that's not in the prelude called "uncons" which is the inverse of uncurried cons.
cons :: a -> [a] -> [a]
uncurry cons :: (a, [a]) -> [a]
uncons :: [a] -> (a, [a])
uncons (x:xs) = (x, xs)
You can use it to implement head as
head = fst . uncons
Why is uncons natural?
You can think of a list as the datatype that's defined through the use of two constructor functions
nil :: [a]
nil = []
cons :: (a, [a]) -> [a]
cons (a,as) = a:as
You can also think of it as the data type which is deconstructed by a function
destruct :: [a] -> Maybe (a, [a])
destruct [] = Nothing
destruct (a:as) = Just (a, as)
It's well beyond this answer to explain why those are so definitively tied to the list type, but one way to look at it is to try to define
nil :: f a
cons :: (a, f a) -> f a
or
destruct :: f a -> Maybe (a, f a)
for any other container type f. You'll find that they all have very close relationships with lists.
You can almost already see uncons in the second case of the definition of destruct, but there's a Just in the way. This is uncons is better paired with head and tail which are not defined on empty lists
head [] = error "Prelude.head"
so we can adjust the previous answer to work for infinite streams. Here we can think of infinite streams as being constructed by one function
data Stream a = Next a (Stream a)
cons :: (a, Stream a) -> Stream a
cons (a, as) = Next a as
and destructed by one function
uncons :: Stream a -> (a, Stream a)
uncons (Next a as) = (a, as)
-- a. k. a.
uncons stream = (head stream, tail stream)
the two being inverses of one another.
Now we can get head for Streams by getting the first element of the return tuple from uncons
head = fst . uncons
And that's what head models in the Prelude, so we can pretend like lists are infinite streams and define head in that way
uncons :: [a] -> (a, [a])
uncons (a:as) = (a, as)
-- a. k. a.
uncons list = (head list, tail list)
head = fst . uncons
Perhaps you're expected write to your own cons List type, then it might make more sense. Although type synonyms can't be recursive, so you end up using a non-tuple data constructor, making the tuple superfluous.. it would look like:
data List a = Nil | List (a, List a)
deriving( Show )
head :: List a -> a
head (List c) = fst c
Like already said in the comments, this is just a silly task and you won't get something you could call a good implementation of head.
Your solution, for those requirements, is just fine – as the only change I would replace (x:y:xs) with (x:y:_) since xs isn't used at all (which would actually cause a compiler warning in some settings). In fact, you could do that with y as well:
myHead (x:_:_) = fst (x, undefined)
There would be alternatives that look perhaps not quite so useless use of fst, i.e. don't just build a tuple by hand and immediately deconstruct it again:
myHead' [x] = x
myHead' xs = myHead' . fst $ splitAt 1 xs
myHead'' = foldr1 $ curry fst
myHead''' = fromJust . find ((==0) . fst) . zip [0..]
but you could rightfully say that these are just ridiculous.

How to define foldM using foldr/foldl (if it is possible)?

I wanted to make a generic function that folds over a wide range of inputs (see Making a single function work on lists, ByteStrings and Texts (and perhaps other similar representations)). As one answer suggested, the ListLike is just for that. Its FoldableLL class defines an abstraction for anything that is foldable. However, I need a monadic fold. So I need to define foldM in terms of foldl/foldr.
So far, my attempts failed. I tried to define
foldM'' :: (Monad m, LL.FoldableLL full a) => (b -> a -> m b) -> b -> full -> m b
foldM'' f z = LL.foldl (\acc x -> acc >>= (`f` x)) (return z)
but it runs out of memory on large inputs - it builds a large unevaluated tree of computations. For example, if I pass a large text file to
main :: IO ()
main = getContents >>= foldM'' idx 0 >> return ()
where
-- print the current index if 'a' is found
idx !i 'a' = print i >> return (i + 1)
idx !i _ = return (i + 1)
it eats up all memory and fails.
I have a feeling that the problem is that the monadic computations are composed in a wrong order - like ((... >>= ...) >>= ...) instead of (... >>= (... >>= ...)) but so far I didn't find out how to fix it.
Workaround: Since ListLike exposes mapM_, I constructed foldM on ListLikes by wrapping the accumulator into the state monad:
modifyT :: (Monad m) => (s -> m s) -> StateT s m ()
modifyT f = get >>= \x -> lift (f x) >>= put
foldLLM :: (LL.ListLike full a, Monad m) => (b -> a -> m b) -> b -> full -> m b
foldLLM f z c = execStateT (LL.mapM_ (\x -> modifyT (\b -> f b x)) c) z
While this works fine on large data sets, it's not very nice. And it doesn't answer the original question, if it's possible to define it on data that are just FoldableLL (without mapM_).
So the goal is to reimplement foldM using either foldr or foldl. Which one should it be? We want the input to be processed lazily and allow for infinte lists, this rules out foldl. So foldr is it going to be.
So here is the definition of foldM from the standard library.
foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM _ a [] = return a
foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
The thing to remember about foldr is that its arguments simply replace [] and : in the list (ListLike abstracts over that, but it still serves as a guiding principle).
So what should [] be replaced with? Clearly with return a. But where does a come from? It won’t be the initial a that is passed to foldM – if the list is not empty, when foldr reaches the end of the list, the accumulator should have changed. So we replace [] by a function that takes an accumulator and returns it in the underlying monad: \a -> return a (or simply return). This also gives the type of the thing that foldr will calculate: a -> m a.
And what should we replace : with? It needs to be a function b -> (a -> m a) -> (a -> m a), taking the first element of the list, the processed tail (lazily, of course) and the current accumulator. We can figure it out by taking hints from the code above: It is going to be \x rest a -> f a x >>= rest. So our implementation of foldM will be (adjusting the type variables to match them in the code above):
foldM'' :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM'' f z list = foldr (\x rest a -> f a x >>= rest) return list z
And indeed, now your program can consume arbitrary large input, spitting out the results as you go.
We can even prove, inductively, that the definitions are semantically equal (although we should probably do coinduction or take-induction to cater for infinite lists).
We want to show
foldM f a xs = foldM'' f a xs
for all xs :: [b]. For xs = [] we have
foldM f a []
≡ return a -- definition of foldM
≡ foldr (\x rest a -> f a x >>= rest) return [] a -- definition of foldr
≡ foldM'' f a [] -- definition of foldM''
and, assuming we have it for xs, we show it for x:xs:
foldM f a (x:xs)
≡ f a x >>= \fax -> foldM f fax xs --definition of foldM
≡ f a x >>= \fax -> foldM'' f fax xs -- induction hypothesis
≡ f a x >>= \fax -> foldr (\x rest a -> f a x >>= rest) return xs fax -- definition of foldM''
≡ f a x >>= foldr (\x rest a -> f a x >>= rest) return xs -- eta expansion
≡ foldr (\x rest a -> f a x >>= rest) return (x:xs) -- definition of foldr
≡ foldM'' f a (x:xs) -- definition of foldM''
Of course this equational reasoning does not tell you anything about the performance properties you were interested in.

Resources