Multiple Statements In Haskell - haskell

How do you have multiple statements in haskell?
Here's what I'm trying to do: given a list such as [a,b,c,d], return every other element, so you get [a,c]. I can see the solution, and here's what I have so far:
fact (xs) | length( xs ) `mod` 2 == 1 = head( xs )
| otherwise = fact(tail( xs ))
This works fine the first time around, but then it quits. What I want to be able to say is return the head, and then call fact(tail(xs)) How do I do that?

The function you specified returns only a single element. You'd need to change it to something like:
fact [] = [] -- can't call tail on a list of length 0!
fact (xs) | length( xs ) `mod` 2 == 1 = head( xs ) : fact(tail(xs))
| otherwise = fact(tail( xs ))
You may find it helpful to write out type signatures to help figure out thinkos like this:
fact :: [a] -> [a] -- convert a list of anything to another (shorter) list
However note that this is very slow - O(n^2) in fact, since it's taking length at each step. A much more haskelly solution would use pattern matching to process two elements at a time:
fact :: [a] -> [a]
-- Take the first element of each two-element pair...
fact (x:_:xs) = x:fact xs
-- If we have only one element left, we had an odd-length list.
-- So grab the last element too.
fact [x] = [x]
-- Return nothing if we have an empty list
fact _ = []

There are no statements in Haskell.
You should not abuse parentheses in Haskell. Rather, you should accustom yourself to the language. So your original code should look like
fact xs | length xs `mod` 2 == 1 = head xs
| otherwise = fact (tail xs)
As bdonlan notes, the function you are looking for is really
fact [] = []
fact [x] = [x]
fact (x:_:xs) = x : fact xs
Suppose we have the list [a, b, c, d]. Let us apply the function and fully evaluate the result.
fact [a, b, c, d] = a : fact [c, d]
= a : c : fact []
= a : c : []
= [a, c]
Note that [a, b, c, d] is exactly the same as a : b : c : d : [] because the two ways of representing lists are interpreted interchangeably by the compiler.

Swapping a semaphore
In fact, we can do it following two possible patterns:
[1,2,3,4,..] becomes [1,3,5,7...]
[1,2,3,4,..] becomes [2,4,6,8...]
Both do the same, but they "begin the counting" the opposite way. Let us implement both of them with the same function! Of course, this function must be parametrized according to the "pattern". Two possible patterns exist, thus, we need a boolean for type for parametrization. Implementation: let us use a boolean parameter as a "flag", "semaphore":
module Alternation where
every_second :: [a] -> [a]
every_second = every_second_at False
every_second_at :: Bool -> [a] -> [a]
every_second_at _ [] = []
every_second_at True (x : xs) = x : every_second_at False xs
every_second_at False (x : xs) = every_second_at True xs
We have used an auxiliary function, bookkeeping the "flag/semaphore": it is swapping it accordingly. In fact, this auxiliary function can be regarded as a generalization of the original task. I think, that is what is called a "worker wrapper" function.
Countdown with an index
The task can be generalized even further. Why not to write a much more general function, which can be parametrized by a "modulus" m, and it "harvests" all mth elems of a list?
every_mth 1 [1,2,3,4,...] yields [1,2,3,4...]
every_mth 2 [1,2,3,4,...] yields [1,3,5...]
every_mth 3 [1,2,3,4,...] yields [1,4,7...]
We can use the same ideas as before, just we have to use more complicated a "semaphore": a natural number instead of a boolean. This is a "countdown" parameter, an index i bookkeeping when it is our turn:
module Cycle where
import Nat (Nat)
every_mth :: Nat -> [a] -> [a]
every_mth 0 = undefined
every_mth m # (i + 1) = every_mth_at m i
We use an auxiliary function (worker wrapper), bookkeeping the countdown index i:
every_mth_at :: Nat -> Nat -> [a] -> [a]
every_mth_at _ _ [] = []
every_mth_at m 0 (x : xs) = x : every_mth m xs
every_nth_at m (i + 1) (x : xs) = every_mth_at m i xs
For simplicity's sake, natural number type is "implemented" here as a mere alias:
module Nat (Nat) where
type Nat = Integer
Maybe, in a number theoretic sense, there are also cleaner alternative approaches, not exactly equivalent to the task You specified, but adjusting seems to be straightforward:
let every_mth 1 [0,1,2,3,4,...] yield [0,1,2,3,4,...]
let every_mth 2 [0,1,2,3,4,...] yield [0,2,4,6,8...]
let every_mth 3 [0,1,2,3,4,...] yield [0,3,6,9...]
thus, it is specified here so that it should provide "incidentally" the list of multiples of the parameter, when applied to the lazy list of all natural numbers.
In its implementation, it is worth using numbers as a "zero-based" index. Instead of "every mth", we say: "use i as an index ranging 0, 1, ..., u = m-1, where u denotes the upper limit of the possible indices. This upper index can be a useful parameter in the auxiliary function, which counts down the index.
module Multiple where
import Nat (Nat)
every_mth :: Nat -> [a] -> [a]
every_mth 0 = undefined
every_mth (u + 1) = countdown u
countdown :: Nat -> [a] -> [a]
countdown = countdown_at 0
countdown_at :: Nat -> Nat -> [a] -> [a]
countdown_at _ _ [] = []
countdown_at 0 u (x : xs) = x : countdown_at u u xs
countdown_at (i + 1) u (x : xs) = countdown_at i u xs

Related

Understanding non-strictness in Haskell with a recursive example

What is the difference between this two, in terms of evaluation?
Why this "obeys" (how to say?) non-strictness
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter _ [] = []
recFilter p (h:tl) = if (p h)
then h : recFilter p tl
else recFilter p tl
while this doesn't?
recFilter :: (a -> Bool) -> [a] -> Int -> [a]
recFilter _ xs 0 = xs
recFilter p (h:tl) len
| p(h) = recFilter p (tl ++ [h]) (len-1)
| otherwise = recFilter p tl (len-1)
Is it possible to write a tail-recursive function non-strictly?
To be honest I also don't understand the call stack of the first example, because I can't see where that h: goes. Is there a way to see this in ghci?
The non-tail recursive function roughly consumes a portion of the input (the first element) to produce a portion of the output (well, if it's not filtered out at least). Then recursion handles the next portion of the input, and so on.
Your tail recursive function will recurse until len becomes zero, and only at that point it will output the whole result.
Consider this pseudocode:
def rec1(p,xs):
case xs:
[] -> []
(y:ys) -> if p(y): print y
rec1(p,ys)
and compare it with this accumulator-based variant. I'm not using len since I use a separate accumulator argument, which I assume to be initially empty.
def rec2(p,xs,acc):
case xs:
[] -> print acc
(y:ys) -> if p(y):
rec2(p,ys,acc++[y])
else:
rec2(p,ys,acc)
rec1 prints before recursing: it does not need to inspect the whole input list to start printing its output. It works in a "steraming" fashion, in a sense. Instead, rec2 will only start to print at the very end, after the input list was completely scanned.
In your Haskell code there are no prints, of course, but you can thing of returning x : function call as "printing x", since x is made available to the caller of our function before function call is actually made. (Well, to be pedantic this depends on how the caller will consume the output list, but I'll neglect this.)
Hence the non-tail recursive code can also work on infinite lists. Even on finite inputs, performance is improved: if we call head (rec1 p xs), we only evaluate xs until the first non-discarded element. By contrast head (rec2 p xs) would fully filter the whole list xs, even we don't need that.
The second implementation does not make much sense: a variable named len will not contain the length of the list. You thus need to pass this, for infinite lists, this would not work, since there is no length at all.
You likely want to produce something like:
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter p = go []
where go ys [] = ys -- (1)
go ys (x:xs) | p x = go (ys ++ [x]) xs
| otherwise = go ys xs
where we thus have an accumulator to which we append the items in the list, and then eventually return the accumulator.
The problem with the second approach is that as long as the accumulator is not returned, Haskell will need to keep recursing until at least we reach weak head normal form (WHNF). This means that if we pattern match the result with [] or (_:_), we will need at least have to recurse until case one, since the other cases only produce a new expression, and it will thus not yield a data constructor on which we can pattern match.
This in contrast to the first filter where if we pattern match on [] or (_:_) it is sufficient to stop at the first case (1), or the third case 93) where the expression produces an object with a list data constructor. Only if we require extra elements to pattern match, for example (_:_:_), it will require to evaluate the recFilter p tl in case (2) of the first implementation:
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter _ [] = [] -- (1)
recFilter p (h:tl) = if (p h)
then h : recFilter p tl -- (2)
else recFilter p tl
For more information, see the Laziness section of the Wikibook on Haskell that describes how laziness works with thunks.

How to fix '*** Exception: Prelude.head: empty list' here

This is a homework , it's to removing the adjacent duplicates.
The result should like this removeAdjacentDuplicates [3,1,2,2,2,2,2,4,4,2,2,3] == [3,1,2,4,2,3]
I knew it's not necessary to use head here, but it's not allowed to use rekursion and List-Comprehensions of Form [e | ...]. Only the function in Prelude is permittet, group und so on , which in other packages are also not allowed. map zip filter concat reverse foldr are recommended.
For example , It's not possible to make this:
removeAdjacentDuplicates :: Eq a => [a] -> [a]
removeAdjacentDuplicates (x:xs#(y:_))
| x == y = x:tail (removeAdjacentDuplicates xs)
| otherwise = x:removeAdjacentDuplicates xs
so I try like this
removeAdjacentDuplicates = foldr (\x result -> if ( x == (head result)) then result else (x : result)) []
but when I test it, it throw *** Exception: Prelude.head: empty list' here out
I have tried to add removeAdjacentDuplicates [] = [] before,
But error is like this
Equations for ‘removeAdjacentDuplicates’ have different numbers of arguments
H7-1.hs:24:1-32
H7-1.hs:25:1-105
|
24 | removeAdjacentDuplicates [] = []
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
I don't understand where the problem is, and how can I solve it?
x == head result dies if result is [] -- and result is definitely [] in the first iteration of foldr, so adding a special case for when the input list would not require foldr to do any iterations is fixing exactly the wrong case!
Instead of trying to extract a value from the result list, you could insert x into a list; so consider using the condition
[x] == take 1 result
instead -- it never dies.
As said by #DanielWagner, head :: [a] -> a will raise an error for empty lists. We can solve this by using take :: Int -> [a] -> [a], or by using pattern matching:
removeAdjacentDuplicates :: (Foldable f, Eq a) => f a -> [a]
removeAdjacentDuplicates = foldr f []
where f x ys#(y:_) | x == y = ys
f x ys = (x:ys)
here ys#(y:_) will match given the list is non-empty, with y as head of the list. In that case we thus check if x == y, and if that holds, we return ys. Otherwise we return (x:ys).

Error on the resulting list of my elemIndices function

The function actually works but the list it returns, if the first element is equal to x, won't be in the correct order.
The function:
myelemIndices :: Eq a => a -> [a] -> [Int]
myelemIndices x [] = []
myelemIndices x l = if posic n l == x
then myReverse (n : myelemIndices x (init l))
else myelemIndices x (init l)
where n = length l - 1
Will return something like:
myelemIndices 1 [1,2,1,2,1]
[2,0,4]
Posic funtion is equal to :
posic :: Int -> [a] -> a
posic 0 (h:t) = h
posic x (a:b) = posic (x-1) b
And myReverse does exactly the same as reverse. I'm not looking for a different funtion that works, just a correction on mine. Thanks in advance!
You're reversing the list every time you find an element. The minimal change here would be to use myElemIndices x (init l) ++ [n] instead of myReverse (n : myelemIndices x (init l))
A first anti-pattern in your code is that you use length. length will usually run in O(n) (with n the number of elements in the list), but furthermore it is troublesome since the list can have infinite length. In that case length will never terminate. In functional programming it is sometimes seen as a sign that something is probably not right.
So the first question is: do we need length. What your code needs to do is return the indices. But say you for instance need to know on what pages in a phone book the name "John" is listed, then you do not need to know in advance how many pages the phone book has: you can simply take a look at the first page. In case it has a person with first name John, then you say that is on page 1, and regardless of that, you move further.
We can use the same approach here. The only thing we need is a parameter that keeps track of the page we are currently looking at. We can introduce this parameter by defining a new function that will do most of the work. So:
myElemIndices :: Eq a => a -> [a] -> [Int]
myElemIndices x l = go 0 l
where go = ...
So we defined a function go, and the first parameter will keep track of the page number. We will need to update that number in case we do recursion. But now of course we still need to define the go function.
The base case is easy: in case we reached the end of the list (phone book), we can say we will not find any occurences anymore. So we can write:
go _ [] = []
This thus means that, regardless of the page number (_), in case there are no pages anymore ([]), we return an empty list as match [].
In case we did not reach the end of the phone book, we can fetch the head h, and the tail t. We will have to check if the head h matches with the queried element x. In case it does, we return the page number, otherwise we don not. Regardless of that, we keep searching for more pages. So we can write:
go i (h:t) | x == h = i : <next-matches>
| otherwise = <next-matches>
the <next-matches> simply is a recursive call where we update the page number (i+1), and we continue with the tail of the list, so:
go i (h:t) | x == h = i : tl
| otherwise = tl
where tl = go (i+1) t
Now we can put that all together into:
myElemIndices :: Eq a => a -> [a] -> [Int]
myElemIndices x l = go 0 l
where go _ [] = []
go i (h:t) | x == h = i : tl
| otherwise = tl
where tl = go (i+1) t
We can still improve the code a bit. First of all, we do not have to write:
myElemIndices x l = go 0 l
Notice that both the head and the body end with l. We can omit this, and turn it into:
myElemIndices x = go 0
Furthermore we do not need the result to be Ints as well. As long as these are Nums, we are fine. So we can generalize this to:
myElemIndices :: (Eq a, Num n) => a -> [a] -> [n]
myElemIndices x l = go 0 l
where go _ [] = []
go i (h:t) | x == h = i : tl
| otherwise = tl
where tl = go (i+1) t

Using fold* to grow a list in Haskell

I'm trying to solve the following problem in Haskell: given an integer return the list of its digits. The constraint is I have to only use one of the fold* functions (* = {r,l,1,l1}).
Without such constraint, the code is simple:
list_digits :: Int -> [Int]
list_digits 0 = []
list_digits n = list_digits r ++ [n-10*r]
where
r = div n 10
But how do I use fold* to, essentially grow a list of digits from an empty list?
Thanks in advance.
Is this a homework assignment? It's pretty strange for the assignment to require you to use foldr, because this is a natural use for unfoldr, not foldr. unfoldr :: (b -> Maybe (a, b)) -> b -> [a] builds a list, whereas foldr :: (a -> b -> b) -> b -> [a] -> b consumes a list. An implementation of this function using foldr would be horribly contorted.
listDigits :: Int -> [Int]
listDigits = unfoldr digRem
where digRem x
| x <= 0 = Nothing
| otherwise = Just (x `mod` 10, x `div` 10)
In the language of imperative programming, this is basically a while loop. Each iteration of the loop appends x `mod` 10 to the output list and passes x `div` 10 to the next iteration. In, say, Python, this'd be written as
def list_digits(x):
output = []
while x > 0:
output.append(x % 10)
x = x // 10
return output
But unfoldr allows us to express the loop at a much higher level. unfoldr captures the pattern of "building a list one item at a time" and makes it explicit. You don't have to think through the sequential behaviour of the loop and realise that the list is being built one element at a time, as you do with the Python code; you just have to know what unfoldr does. Granted, programming with folds and unfolds takes a little getting used to, but it's worth it for the greater expressiveness.
If your assignment is marked by machine and it really does require you to type the word foldr into your program text, (you should ask your teacher why they did that and) you can play a sneaky trick with the following "id[]-as-foldr" function:
obfuscatedId = foldr (:) []
listDigits = obfuscatedId . unfoldr digRem
Though unfoldr is probably what the assignment meant, you can write this using foldr if you use foldr as a hylomorphism, that is, building up one list while it tears another down.
digits :: Int -> [Int]
digits n = snd $ foldr go (n, []) places where
places = replicate num_digits ()
num_digits | n > 0 = 1 + floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n, ds) = let (q,r) = n `quotRem` 10 in (q, r : ds)
Effectively, what we're doing here is using foldr as "map-with-state". We know ahead of time
how many digits we need to output (using log10) just not what those digits are, so we use
unit (()) values as stand-ins for those digits.
If your teacher's a stickler for just having a foldr at the top-level, you can get
away with making go partial:
digits' :: Int -> [Int]
digits' n = foldr go [n] places where
places = replicate num_digits ()
num_digits | n > 0 = floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n:ds) = let (q,r) = n `quotRem` 10 in (q:r:ds)
This has slightly different behaviour on non-positive numbers:
>>> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits' 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits 0
[]
>>> digits' 0
[0]
>>> digits (negate 1234567890)
[]
>>> digits' (negate 1234567890)
[-1234567890]

Checking for empty list in Haskell: Is (length list == 0) or (list == []) more efficient?

Say I want to check if a list is empty in a guard in Haskell there are two options:
length list == 0
list == []
Which of these two logical tests are more efficient? I'm inclined to say the empty list test because relies on more basic constructs rather than the prelude function length but I'm not sure.
length list == 0 needs to traverse the whole list to get its length, which means it is O(n). list == [] yields an Eq constraint on the element type. null list runs in constant time and has no typeclass constraints.
However, there is a neat trick to do something like length list == 0 which has the advantage that it generalizes nicely to length list1 == length list2 without going through the longer list: you can use genericLength with a sufficiently lazy representation of natural numbers so that comparison will only force traversing the shorter of the lists.
One example is to use the Natural type:
import Data.Number.Natural
import Data.List (genericLength)
nats :: [Int]
nats = iterate succ 0
areThereTenNats :: Bool
areThereTenNats = genericLength nats >= (10 :: Natural)
You can check if your list is empty in constant time with null list, which returns a boolean.
Prelude> null []
True
Prelude> null [1]
False
Prelude> null ""
True
Prelude> null "Test"
False
As others have indicated, the best way to check if a list is empty (and nothing more) is to use
null :: Foldable f => f a -> Bool
which can be used at type
null :: [a] -> Bool
If you want to check if a list is empty because you want to look at its elements otherwise, you generally should be using pattern matching instead:
f [] = something
f (x : xs) = something using x and/or xs
If you want to compare the lengths of two lists (and no more), the best way is usually something like
compareLength :: [a] -> [b] -> Ordering
compareLength [] [] = EQ
compareLength [] (_ : _) = LT
compareLength (_ : _) [] = GT
compareLength (_ : xs) (_ : ys) =
compareLength xs ys
The best way to check how the length of a list compares to a certain number is
compareToLength :: Foldable f
=> f a -> Int -> Ordering
compareToLength = foldr go (compare 0) where
go _ r n | n <= 0 = GT
| otherwise = r $! n - 1

Resources