How can i solve this in haskell? [duplicate] - haskell

This question already has answers here:
Better exception for non-exhaustive patterns in case
(2 answers)
Closed 4 years ago.
I got this code to make a transposed matrix, but it doesn't work 100% fine.
type Mat a = [[a]]
transpose' :: Eq a => Mat a -> Mat a
transpose' [] = []
transpose' (h:t) = primelem (h:t):transpose' (eliminate' (h:t))
primelem :: Mat a -> [a]
primelem [] = []
primelem [[x]] = [x]
primelem ((x:xs):t) = x : primelem t
eliminate' :: Eq a => Mat a -> Mat a
eliminate' [] = []
eliminate' (h:t) = (delete (head h) h):eliminate' t
*Main> transpose' [[1,2,3],[0,4,5],[0,06]]
[[1,0,0],[2,4,6],[3,5*** Exception:(..)Non-exhaustive patterns in function primelem
I am trying to figure it out, but i really don't know which case is missing.

To discover which cases you are missing, you should turn on warnings using the -Wall flag, as shown in the GHCi session below.
> :set -Wall
> type Mat a = [[a]]
> :{
| primelem :: Mat a -> [a]
| primelem [] = []
| primelem [[x]] = [x]
| primelem ((x:xs):t) = x : primelem t
| :}
<interactive>:5:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘primelem’: Patterns not matched: ([]:_)
<interactive>:7:14: warning: [-Wunused-matches]
Defined but not used: ‘xs’
So, the case you are missing is:
primelem ([]:t) = ...

You're over-thinking this. A list of empty lists is its own transpose.
transpose m | all null m = []
| any null m = error "Not a matrix"
Otherwise, take the first element of each list as the first row of the transpose, and transpose the remaining matrix as the rest of the transpose.
transpose m = map head m : transpose (map tail m)
This function is effectively total, failing only on those lists-of-lists that aren't actually matrices. The fact that it fails late on non-matrix values is a bit of a wart:
> transpose [[1,2], [3]]
[[1,3]*** Exception: Not a matrix
CallStack (from HasCallStack):
error, called at tmp.hs:3:28 in main:Main
If you want to handle invalid matrices a little more cleanly, return a Maybe (Mat a) instead.
transpose :: Mat a -> Maybe (Mat a)
transpose m | all null m = Just []
| any null m = Nothing
| otherwise = ((map head m):) <$> transpose (map tail m)

Related

Return the item at the specified position in list

I'm trying to find out en element at a particular position in a list using recursive function. The function takes 2 parameter, an int & list. int is the position of the item in the list. I have specified 2 cases, 1st case for empty list provided and 2nd case for non- empty list.
.hs code
findKthElem :: Ord a => Int -> [a] -> a
findKthElem x [] = error "empty list provided"
findKthElem x (y:ys) = if x==1 then y else findKthElem (x-1) ys
Input
*Main> findKthElem 0 [1..99]
Output
** Exception: empty list provided
Expected Output
1
Since I'm a newbie in Haskell I can't understand where I'm going wrong. Please Help.
An approach using guards to match against different index values:
findKthElem :: Ord a => Int -> [a] -> a
findKthElem _ [] = error "empty list provided"
findKthElem i (x:xs) | i < 0 = error "invalid index"
| i == 0 = x
| otherwise = findKthElem (i - 1) xs
You can also use the Maybe monad to remain error free:
findKthElem :: Ord a => Int -> [a] -> Maybe a
findKthElem _ [] = Nothing
findKthElem i (x:xs) | i < 0 = Nothing
| i == 0 = Just x
| otherwise = findKthElem (i - 1) xs

non-exhaustive pattern matches on list of tuples [duplicate]

This question already has answers here:
Non exhaustive pattern in function noThirds
(3 answers)
Closed 5 years ago.
I'm not sure what I'm missing here, but I have been unable to get the pattern matching on checkDiff to work in the code below. GHCi report "non-exhaustive patterns in function checkDiff. The code is:
import Data.Array.Unboxed
primes :: [Int]
primes = 2 : oddprimes ()
where
oddprimes () = 3 : sieve (oddprimes ()) 3 []
sieve (p:ps) x fs = [i*2 + x | (i,True) <- assocs a]
++ sieve ps (p*p) ((p,0) :
[(s, rem (y-q) s) | (s,y) <- fs])
where
q = (p*p-x)`div`2
a :: UArray Int Bool
a = accumArray (\ b c -> False) True (1,q-1)
[(i,()) | (s,y) <- fs, i <- [y+s, y+s+s..q]]
takePrimes :: [Int] -> [(Int,Int)]
takePrimes [] = []
takePrimes [x] = []
takePrimes (x:y:zs) = if y - x > 2 then (x,y) : takePrimes (y:zs) else takePrimes (y:zs)
checkDiff :: [(Int,Int)] -> Int
checkDiff [] = 0
checkDiff [(0,_)] = 0
checkDiff [(_,0)] = 0
checkDiff [(a,b)] = sum $ [x | x <- [(a + 1)..(b - 1)], totalFactors a == totalFactors (a + 1)]
totalFactors :: Int -> Int
totalFactors n = length $ [x | x <- [2..(div n 2)], rem n x == 0]
Please help.
checkDiff only handles lists of length zero and one. It is probably called with a longer list, triggering the non-exhaustiveness error.
You should turn on warnings with the -Wall flag. If you do, GHC will report such problems at compile time instead.

Haskell: Exception <<loop>> on recursive data entry

So I'm trying to make a little program that can take in data captured during an experiment, and for the most part I think I've figured out how to recursively take in data until the user signals there is no more, however upon termination of data taking haskell throws Exception: <<loop>> and I can't really figure out why. Here's the code:
readData :: (Num a, Read a) => [Point a] -> IO [Point a]
readData l = do putStr "Enter Point (x,y,<e>) or (d)one: "
entered <- getLine
if (entered == "d" || entered == "done")
then return l
else do let l = addPoint l entered
nl <- readData l
return nl
addPoint :: (Num a, Read a) => [Point a] -> String -> [Point a]
addPoint l s = l ++ [Point (dataList !! 0) (dataList !! 1) (dataList !! 2)]
where dataList = (map read $ checkInputData . splitOn "," $ s) :: (Read a) => [a]
checkInputData :: [String] -> [String]
checkInputData xs
| length xs < 2 = ["0","0","0"]
| length xs < 3 = (xs ++ ["0"])
| length xs == 3 = xs
| length xs > 3 = ["0","0","0"]
As far as I can tell, the exception is indication that there is an infinite loop somewhere, but I can't figure out why this is occurring. As far as I can tell when "done" is entered the current level should simply return l, the list it's given, which should then cascade up the previous iterations of the function.
Thanks for any help. (And yes, checkInputData will have proper error handling once I figure out how to do that.)
<<loop>> basically means GHC has detected an infinite loop caused by a value which depends immediately on itself (cf. this question, or this one for further technical details if you are curious). In this case, that is triggered by:
else do let l = addPoint l entered
This definition, which shadows the l you passed as an argument, defines l in terms of itself. You meant to write something like...
else do let l' = addPoint l entered
... which defines a new value, l', in terms of the original l.
As Carl points out, turning on -Wall (e.g. by passing it to GHC at the command line, or with :set -Wall in GHCi) would make GHC warn you about the shadowing:
<interactive>:171:33: warning: [-Wname-shadowing]
This binding for ‘l’ shadows the existing binding
bound at <interactive>:167:10
Also, as hightlighted by dfeuer, the whole do-block in the else branch can be replaced by:
readData (addPoint l entered)
As an unrelated suggestion, in this case it is a good idea to replace your uses of length and (!!) with pattern matching. For instance, checkInputData can be written as:
checkInputData :: [String] -> [String]
checkInputData xs = case xs of
[_,_] -> xs ++ ["0"]
[_,_,_] -> xs
_ -> ["0","0","0"]
addPoint, in its turn, might become:
addPoint :: (Num a, Read a) => [Point a] -> String -> [Point a]
addPoint l s = l ++ [Point x y z]
where [x,y,z] = (map read $ checkInputData . splitOn "," $ s) :: (Read a) => [a]
That becomes even neater if you change checkInputData so that it returns a (String, String, String) triple, which would better express the invariant that you are reading exactly three values.

Write the recursive function adjuster

Write the recursive function adjuster. Given a list of type
x, an int and an element of type x, either remove from the front of the
list until it is the same length as int, or append to the end of the list
until it is the same length as the value specified by the int.
expected:
adjuster [1..10] (-2) 2 -> *** Exception: Invalid Size
adjuster [1..10] 0 2 -> []
adjuster "apple" 10 ’b’ -> "applebbbbb"
adjuster "apple" 5 ’b’ -> "apple"
adjuster "apple" 2 ’b’ -> "le"
adjuster [] 3 (7,4) -> [(7,4),(7,4),(7,4)]
What i did:
adjuster (x:xs) count b
| count < 0 = error "Invalid Size"
| count == 0 = []
| count < length xs = adjuster xs (count-1) b
| otherwise = (adjuster xs (count-1) b):b
the error that I'm getting:
* Occurs check: cannot construct the infinite type: t ~ [t]
Expected type: [t]
Actual type: [[t]]
* In the expression: (adjuster xs (count - 1) b) : b
In an equation for `adjuster':
adjuster (x : xs) count b
| count < 0 = error "Invalid Size"
| count == 0 = []
| count < length xs = adjuster xs (count - 1) b
| otherwise = (adjuster xs (count - 1) b) : b
* Relevant bindings include
b :: [[t]] (bound at code01.hs:21:23)
adjuster :: [a] -> Int -> [[t]] -> [t] (bound at code01.hs:21:1)
I'm new in haskell.I'll really appreciate some help.
You are trying to construct a list within lists within lists and so on and so forth …
Why is this?
(:) :: a -> [a] -> [a]
The colon operator takes an element and a list of such elements as an argument and constructs a list from that (by prepending that element).
In your case if (adjuster ...) had type [a] then b must be of type [[a]], by line 4 which is the same as the end result, but line 3 says the type is [a] - which is different. This is what GHC tries to tell you.
How to fix it?
First of all, it is always a good advice to add a type signature to every top level function:
adjuster :: [a] -> Int -> a -> [a]
which should clean up your error-message and keep you honest, when implementing your function.
So how to fix this: - you could use b:adjuster xs (count-1) b but this would yield a result in the wrong order - so
choose a different operator: (++) and wrap the b inside a list.
| otherwise = (adjuster xs (count-1) b)++[b]
Now a few more hints:
turn on -Wall when you compile your file - this will show you that you missed the case of adjuster [] ...
using length is a relatively expensive operation - as it needs to traverse the full list to be calculated.
As an exercise - try to modify your function to not use length but only work with the base cases [] for list and 0 for count (here the function replicate might be helpful).
Here is another approach, without error handling
adjuster xs n v = tnr n $ (++) (replicate n v) $ tnr n xs
where tnr n r = take n $ reverse r
if you play with the signature, perhaps cleaner this way
adjuster n v = tnr . (++) (replicate n v) . tnr
where tnr = take n . reverse

Error: Non-exhaustive patterns in Haskell

I have some code that deals with a list of lists (that represents a matrix). Each cell is an N or a B. I want to represent the matrix with the number of Ns for each line. For example: [[B,B,N],[N,N,N]] is represented by [1,3].
Here's my code:
data Case = B|N deriving (Show, Eq)
type Grille =[[Case]]
g0,g1 :: Grille
g0 = [[B,B,B,B,B,B,N],[B,B,N,B,N,B,B],[N,B,N,N,N,N,N],[B,B,B,N,N,B,N],[N,N,N,B,B,B,B],[B,B,B,N,N,B,N]]
g1 = [[B,B,B,B,B,B,B],[B,B,N,N,N,B,B],[B,B,N,N,N,N,N],[B,B,B,N,N,N,N],[N,N,N,B,B,B,B],[B,B,B,N,B,B,B]]
projH :: Grille -> [Int]
projH [[]] = []
projH (x:xg) = testCase(x) ++ projH(xg)
testCase :: [Case] -> [Int]dans une ligne
testCase [] = [0]
testCase (x:xs)
| x == N = [head(testCase(xs))+1]
| otherwise = testCase(xs)
The problem is in the function projH, I'm obviously missing a pattern, but I do handle the case with [[],...] with the testCase function and the [[]] case. I don't know why it throws me this error:
*Main> projH g0
[1,2,6,3,3,3*** Exception: devoir.hs:(17,1)-(18,39): Non-exhaustive patterns in function projH
projH [] = []
instead of your
projH [[]] = []
As the case you wrote is already handled by the other statement by assigning x = [] and xg = []

Resources