How to report an error in Haskell code - haskell

I am writing a program that returns every rth element from a list. The list can be any type. I want to report an error when r is zero but my code isn't working (it is working fine when I comment out the error line). Can anyone tell me how to report an error in this situation
rthElem :: Int -> [a] -> [a]
rthElem _ [] = []
rthElem 0 (x:xs) = "Error"
rthElem n (x:xs) = rthElem' n 1 (x:xs) where
rthElem' n i (x:xs) = (if (n `divides` i) then
[x] else
[])
++ (rthElem' n (i+1) xs)
rthElem' _ _ [] = []
divides x y = y `mod` x == 0

You could use Maybe or Either in this case.
This is how Maybe looks. Nothing will be our "error".
rthElem :: Int -> [a] -> Maybe [a]
rthElem _ [] = Just []
rthElem 0 (x:xs) = Nothing
rthElem n (x:xs) = Just (rthElem' n 1 (x:xs)) where
rthElem' n i (x:xs) = (if (n `divides` i) then
[x] else
[])
++ (rthElem' n (i+1) xs)
rthElem' _ _ [] = []
divides x y = y `mod` x == 0
main :: IO ()
main = case (rthElem 0 [1..5]) of
Nothing -> putStrLn "Error"
Just elm -> print elm
Another way is using Either. Either will return Left or Right. Left will be our "error".
rthElem :: Int -> [a] -> Either String [a]
rthElem _ [] = Right []
rthElem 0 (x:xs) = Left "Error"
rthElem n (x:xs) = Right (rthElem' n 1 (x:xs)) where
rthElem' n i (x:xs) = (if (n `divides` i) then
[x] else
[])
++ (rthElem' n (i+1) xs)
rthElem' _ _ [] = []
divides x y = y `mod` x == 0
main :: IO ()
main = case (rthElem 0 [1..5]) of
Left err -> putStrLn err
Right elm -> print elm
The best way is using Either. Read more about error handling here.

If you really want to print an error and show it you could use the error function, error :: String -> a
rthElem 0 (x:xs) = error "Error msg here"
But there is a plenty better ways to do this , and you should figure out which one fits in your case , you can use Maybe, Either even monads , here is an interesting link with examples http://www.randomhacks.net/2007/03/10/haskell-8-ways-to-report-errors/

You could use exceptions but you'd also have to transform your function into an IO action.
rthElem :: Int -> [a] -> IO [a]
rthElem _ [] = return []
rthElem 0 _ = ioError $ userError "Error"
rthElem n l = return $ rthElem' n 1 l where
rthElem' n i (x:xs) = (if (n `divides` i) then
[x] else
[])
++ (rthElem' n (i+1) xs)
rthElem' _ _ [] = []
divides x y = y `mod` x == 0

Related

Haskell: Change the (n,m)th element in a Lists in List

The replaceAtMatrix function should take in a tuple (Int,Int) that decides what position is the value that needs to be changed, a value to be changed to, and the List in List [[a]].
If the tuple's values exceed the lists length the original [[a]] needs to be returned.
replaceAtList :: Int -> a -> [a] -> [a]
replaceAtList _ _ [] = []
replaceAtList 0 a (_:xs) = a:xs
replaceAtList number a (x:xs)
| number < 0 = x:xs
| number > (length (x:xs)-1) = x:xs
| otherwise = x : replaceAtList (number-1) a xs
replaceAtMatrix :: (Int,Int) -> a -> [[a]] -> [[a]]
replaceAtMatrix _ _ [] = []
replaceAtMatrix (0,num2) a (x:xs) = replaceAtList num2 a x : xs
replaceAtMatrix (num1,num2) a (x:xs)
| num1 < 0 = x:xs
| num1 > (length (x:xs)-1) = x:xs
| num2 < 0 = x:xs
| num2 > (length (x:xs)-1) = x:xs
| otherwise = x : replaceAtMatrix (num1-1,num2) a xs
There are test for which I checked, and it passes most of them, but there's one where it goes in an infinite cycle. Here's the tests that work.
replaceAtMatrix (-1,0) 'A' ["bcd","lds","rtz"] == ["bcd","lds","rtz"]
replaceAtMatrix (0,0) 'A' ["bcd","lds","rtz"] == ["Acd","lds","rtz"]
replaceAtMatrix (2,0) 'A' ["bcd","lds","rtz"] == ["bcd","lds","Atz"]
replaceAtMatrix (3,0) 'A' ["bcd","lds","rtz"] == ["bcd","lds","rtz"]
replaceAtMatrix (2,2) 'A' ["bcd","lds","rtz"] == ["bcd","lds","rtA"]
And here's the one that doesn't.
Edit: I just realized it's probaly beacuse I use length on an infinite list. How can I rewrite it without using length?
take 5 (replaceAtMatrix (1,2) 100 [[1..],[1,11..],[],[12,13,14]] !! 1) == [1,11,100,31,41]
Without the guard, I get a variable not in scope error.
replaceAtList :: Int -> a -> [a] -> [a]
replaceAtList _ _ [] = []
replaceAtList 0 a (_:xs) = a:xs
replaceAtList number a (x:xs) = x : replaceAtList (number-1) a xs
replaceAtMatrix :: (Int,Int) -> a -> [[a]] -> [[a]]
replaceAtMatrix _ _ [] = []
replaceAtMatrix (0,num2) a (x:xs) = replaceAtList num2 a x : xs
replaceAtMatrix (num1,num2) a (x:xs) = x : replaceAtMatrix (num1-1,num2) a xs
I think you have your answer, and can make progress, but I thought it might be interesting to show you an alternate implementation. There's some repetition in your existing code of traversing a list to a specific spot, and then making a change. Here's an idea for how you might implement that just once:
onIndex :: Int -> (a -> a) -> ([a] -> [a])
onIndex n f = if n < 0 then id else loop n where
loop _ [] = []
loop 0 (x:xs) = f x:xs
loop n (x:xs) = x:loop (n-1) xs
Rather than taking an element and replacing that element, this takes an arbitrary editing function and applies that function to the element at the appropriate position. We can use this to replace an element with value foo using const foo as the editing function. But, and this is the key thing, we can also use an editing function that itself calls onIndex!
replaceAtMatrix :: (Int, Int) -> a -> [[a]] -> [[a]]
replaceAtMatrix (m, n) = onIndex m . onIndex n . const
Don't use length. This will error on infinite lists: you do not need this: in case the number > length somelist, eventually it will reach the end of the list:
replaceAtList :: Int -> a -> [a] -> [a]
replaceAtList _ _ [] = []
replaceAtList n _ xs
| n < 0 = xs
replaceAtList 0 a (_:xs) = a:xs
replaceAtList number a (x:xs) = x : replaceAtList (number-1) a xs
replaceAtMatrix :: (Int,Int) -> a -> [[a]] -> [[a]]
replaceAtMatrix _ _ [] = []
replaceAtMatrix (m, _) _ xs
| m < 0 = xs
replaceAtMatrix (0,num2) a (x:xs) = replaceAtList num2 a x : xs
replaceAtMatrix (num1,num2) a (x:xs) = x : replaceAtMatrix (num1-1,num2) a xs

How can I extract list of similar elements from a haskell list

Given a list such as [1,0,0,0,3,0,0,0,0,2,4,0,0] and an index, how can I extract consecutive patterns of 0 in Haskell. For example if the given index is between 1 and 3 inclusive, the result is [0,0,0] if it is between 5 and 8 [0,0,0,0] and so on
First, build a list where run lengths are stored for each number:
runs :: (Eq a) => [a] -> [(a, Int)]
runs = map (head &&& length) . group
so e.g.
runs [1,0,0,0,1,0,0,0,0,1,1,0,0] == [(1,1),(0,3),(1,1),(0,4),(1,2),(0,2)]
Then, index into this list by walking it in run length-sized steps:
indexRuns :: Int -> [(a, Int)] -> [a]
indexRuns i [] = error "Index out of bounds"
indexRuns i ((x, l):rs)
| i < l = replicate l x
| otherwise = indexRuns (i - l) rs
You can do this in O(n) time:
extract :: Eq a => Int -> [a] -> [a]
extract _ [] = []
extract idx (x:xs) = extract' x [x] 1 xs
where
extract' _ _ _ [] = [] -- Index out of bounds
extract' v vs n (r : rest)
| idx == n = vs ++ (takeWhile (== v) rest)
| (v == r) = extract' v (r:vs) (n+1) rest
| otherwise = extract' r [r] (n+1) rest
This will count the number of zeros around the index
numZeros::Int->[Int]->Int
numZeros 0 (1:_) = 0
numZeros i (1:rest) = numZeros (i-1) rest
numZeros i theList
| i < zeroLen = zeroLen
| otherwise = numZeros (i-zeroLen) $ drop zeroLen theList
where
zeroLen = length (takeWhile (==0) theList)
You can replicate 0 the appropriate number of times to get the final list.
f = f' (takeWhile (== 0)) where
f' c n xs | n < 0 || null xs = []
f' c n (1:xs) = f (n - 1) xs
f' c 0 xs = c xs
f' c n (0:xs) = f' ((0:) . c) (n - 1) xs
Or even more obfuscated
f n xs = g (splitAt n xs) >>= takeWhile (== 0) where
g (xs, ys#(0:_)) = [reverse xs, ys]
g _ = []
Some tests:
main = mapM_ (\i -> print $ (i, f i [1,0,0,0,1,0,0,0,0,1,1,0,0])) [-1..13]
prints
(-1,[])
(0,[])
(1,[0,0,0])
(2,[0,0,0])
(3,[0,0,0])
(4,[])
(5,[0,0,0,0])
(6,[0,0,0,0])
(7,[0,0,0,0])
(8,[0,0,0,0])
(9,[])
(10,[])
(11,[0,0])
(12,[0,0])
(13,[])

Drop nth Element from list

I have been teaching myself Haskell for a month or so and today I was reading the solution of 16th problem and came up with a question.
Here is a link : http://www.haskell.org/haskellwiki/99_questions/Solutions/16
Basically, this question asks to make a function that drops every N'th element from a list.
For example,
*Main> dropEvery "abcdefghik" 3
"abdeghk"
The first solution in the link is
dropEvery :: [a] -> Int -> [a]
dropEvery [] _ = []
dropEvery (x:xs) n = dropEvery' (x:xs) n 1
where
dropEvery' (x:xs) n i = (if (n `divides` i) then [] else [x])++ (dropEvery' xs n (i+1))
dropEvery' [] _ _ = []
divides x y = y `mod` x == 0
My question is why dropEvery defines the case of empty lists while dropEvery' can take care of empty list?
I think dropEvery [] _ = [] can be simply eliminated and modifying a bit of other sentences as following should work exactly the same as above and looks shorter.
dropEvery :: [a] -> Int -> [a]
dropEvery xs n = dropEvery' xs n 1
where
dropEvery' (x:xs) n i = (if (n `divides` i) then [] else [x])++ (dropEvery' xs n (i+1))
dropEvery' [] _ _ = []
divides x y = y `mod` x == 0
Can anyone help me figure out about this?
I think they are the same and the author could have simplified the code as you suggested. For the heck of it I tried both versions with QuickCheck and they seem to be the same.
import Test.QuickCheck
dropEvery :: [a] -> Int -> [a]
dropEvery [] _ = []
dropEvery (x:xs) n = dropEvery' (x:xs) n 1
where
dropEvery' (x:xs) n i = (if (n `divides` i) then [] else [x])++ (dropEvery' xs n (i+1))
dropEvery' [] _ _ = []
divides x y = y `mod` x == 0
dropEvery2 :: [a] -> Int -> [a]
dropEvery2 xs n = dropEvery' xs n 1
where
dropEvery' (x:xs) n i = (if (n `divides` i) then [] else [x])++ (dropEvery' xs n (i+1))
dropEvery' [] _ _ = []
divides x y = y `mod` x == 0
theyAreSame xs n = (dropEvery xs n) == (dropEvery2 xs n)
propTheyAreSame xs n = n > 0 ==> theyAreSame xs n
And in ghci you can do
*Main> quickCheck propTheyAreSame
+++ OK, passed 100 tests.
I also tested a few corner cases by hand
*Main> dropEvery [] 0
[]
*Main> dropEvery2 [] 0
[]
*Main> dropEvery [] undefined
[]
*Main> dropEvery2 [] undefined
[]
So them seem to the same.
So our learning outcomes:
Quickcheck is perfect for this kind of stuff
Don't underestimate yourself. :)

Haskell, return a tuple

i have this code, it's the formulae of combination without repetitions:
combinaciones :: Int ->[Int]->[[Int]]
combinaciones 0 _ = [[]]
combinaciones _ [] = []
combinaciones k (x:xs) = [x:ys | ys <- combinaciones (k - 1) xs] ++ combinaciones k xs
combinationsN :: Int ->Int->[[Int]]
combinationsN n k = combinaciones k [1..n]
My problem is that i want return a list of lists with the number of lists in the list, a couple: ([[Int]], Int). How can i do that?
Here is the simple version - it's probably possible to do it more efficiently by counting along, but this is what I can come up with at 1am.
combinationsWithCount :: Int -> [Int] -> ([[Int]], Int)
combinationsWithCount n xs = let cs = combinaciones n xs
in (cs, length cs)
Edit: OK, let me try to write the smart version too.
combinaciones :: Int -> [Int] -> ([[Int]], Int)
combinaciones 0 _ = ([[]], 1)
combinaciones _ [] = ([], 0)
combinaciones k (x:xs) =
let (first, firstN) = combinaciones (k - 1) xs
(second, secondN) = combinaciones k xs
in ([x:ys | ys <- first] ++ second, firstN + secondN)
Absolutely no guarantees that this does the right thing, I'm half-asleep. ;-)

Lambda expression parse error on ")"

My task is to re-implement this function
divn :: Integer -> [Integer] -> [Integer]
divn _ [] = []
divn n (x:xs) | mod x n == 0 = x : divn n xs
| otherwise = divn n xs
using 'foldr'.
What I did:
divn' _ [] = []
divn' n (x:xs) = foldr (\x -> if (mod x n == 0) (x:) ([]++)) [] xs
I thought this would work. Actually it doesn't even compile, but says: "Parse error on input ")".
As I didn't find any errors, I decided to re-write if as if' an now its working...
if' True x _ = x
if' False _ x = x
divn' _ [] = []
divn' n (x:xs) = foldr (\x -> if' (mod x n == 0) (x:) ([]++)) [] xs
Does anyone know where's the error?
Thanks!
if needs a then and an else in Haskell,
(\x -> if (mod x n == 0) (x:) ([]++))
should be
(\x -> if (mod x n == 0) then (x:) else id)
Apart from what Daniel Fischer said, you don't need any separate cases: there's no recursion, the empty list case will be handled by foldr. In your code, the first x is always ignored! Correct is
divn' n xs = foldr (\x -> if x`mod`n == 0 then (x:) else id) [] xs
or, by η-reduction,
divn' n = foldr (\x -> if x`mod`n == 0 then (x:) else id) []
Of course, it would be far more idiomatic to simply do
divn'' n = filter ((==0) . (`mod`n))

Resources