I have two functions. The first one gives true if all elements of the list are zero
allZero :: [Int] -> Bool
allZero [] = False
allZero [0] = True
allZero (x:xs)
| x == 0 && allZero xs = True
|otherwise = False
The second function gives true if at least one element of the list is zero
oneZero :: [Int] -> Bool
oneZero [] = False
oneZero (x:xs)
| x == 0 = True
| otherwise = oneZero xs
Maybe there is another way to solve this problems. For example with map or foldr?
Thank you
foldr function works so:
Suppose, you have list [1, 2, 3]. Let's write this list as (:) 1 ((:) 2 ((:) 3 [])), where each element has type a. Function foldr takes function f of a -> b -> b type and starting element z of b type, and just replace [] to z and : to f. So, foldr f z ((:) 1 ((:) 2 ((:) 3 []))) == f 1 (f 2 (f 3 z)).
So, you can define your functions so:
allZero = foldr (\x -> x == 0 &&) True
oneZero = foldr (\x -> x == 0 ||) False
foldr basically takes your guard as its folding function:
allZero = foldr (\x acc -> x == 0 && acc) True
acc (for accumulator) is the already-computed value of the recursive call. Being right-associative, the first non-zero value in the list short-circuits the evaluation of the fold function on the rest of the list.
(Note that allZero [] == True by convention. The "hypothesis" is that allZero xs is true, with evidence in the form of a non-zero element to falsify the hypothesis. No elements in the list, no evidence to contradict the hypothesis.)
I leave it as an exercise to adapt this to compute oneZero.
Related
Can some one tell me, why i am getting the following error:
error: [-Wincomplete-patterns, -Werror=incomplete-patterns]
Pattern match(es) are non-exhaustive
In a case alternative: Patterns not matched: []
|
54 | case list of
| ^^^^^^^^^^^^...
Thats my test:
testMinBy :: Test
testMinBy = TestCase $ do
assertEqual "test1" (minBy (\x -> -x) [1,2,3,4,5]) 5
assertEqual "test2" (minBy length ["a", "abcd", "xx"]) "a"
minBy :: Ord b => (a -> b) -> [a] -> a
minBy measure list =
case list of
(x:y:xs) -> minBy measure (if measure x > measure y then y:xs else x:xs)
[x] -> x
Your pattern does not matches with the empty list. Indeed, that is what the error is saying. You can match the empty list, for example with:
minBy :: Ord b => (a -> b) -> [a] -> a
minBy measure list =
case list of
(x:y:xs) -> minBy measure (if measure x > measure y then y:xs else x:xs)
[x] -> x
[] -> error "Empty list"
Your function however is not very efficient: it will recalculate measure multiple times if an item is the current minimum, and will also pack and unpack lists. You can work with an accumulator here, like:
minBy :: Ord b => (a -> b) -> [a] -> a
minBy _ [] = error "Empty list"
minBy f (x:xs) = go xs x (f x)
where go [] y _ = y
go (y₁:ys) y₀ fy₀
| fy₁ < fy₀ = go ys y₁ fy₁
| otherwise = go ys y₀ fy₀
where fy₁ = f y₁
This means it only once has to check for an empty list, and then knows for sure that this is a non-empty list if it enumerates. It also will determine the f of each item exactly once, and uses accumulators to avoid packing and unpacking a "cons".
Condition: Function containing character c and string xs, where all c's are replaced by '*'.
`
zensiert :: [Char] -> String
zensiert c (x:xs)
| x == c = x == '*'
| otherwise = zensiert c (x:xs)
`
The map function and list generators are prohibited. Example: zensiert 'l' ''Rolls a ball around the corner and falls down.'' returns:''Ros a ba around the corner and fas down.''
Because of the example is was thinking that is at the beginning a list in a char that leads to a string, but it didn ´ t work. Because of that I would be very conceivable, if someone would look over there times
Now I tried so:
zensiert :: [Char] -> String
zensiert (x:xs) = if x == 'c' then ('*' : zensiert xs) else (x : zensiert xs)
But there is the problem, if i give zensiert 'l' "Hello", the terminal says: Couldn't match expected type ‘[Char] -> t’ with actual type ‘[Char]’
First, the type signature should be
zensiert :: Char -> String -> String
You'll take a character and a string as arguments, and return a new string.
== is not an assignment operator, even if Haskell did have assignments. Your second definition would be fine (for replacing hard-coded 'c's, anyway), except you don't define it for the empty string the recursive call will eventually receive, and you incorrectly call it with a Char argument it won't use.
The correct definition takes a Char argument and uses that instead of the Char literal 'c'.
zensiert :: Char -> String -> String
zensiert _ [] = []
zensiert c (x:xs) = if x == c then ('*' : zensiert xs) else (x : zensiert xs)
A simpler approach would be to use map to apply a function that replaces 'c' with '*' to a list, whether it is empty or not.
zensiert c xs = map (\x -> if x == c then '*' else x) xs
or
zensiert c xs = map f xs
where f 'c' = '*'
f x = x
Whenever you are defining recursive functions, you need at least one base case that exists the recursion, and at least one case that calls the function recursively in a way that converges on the base case.
If you're dealing with strings, the base case is often an empty string, and we converge the making the input string closer to an empty string.
Replacing any character with '*' in an empty string gives us just an empty string, so the base case is simple. For the update case, we just have to decide what to append to recursively calling the function on the "tail" of the string.
ghci> :{
ghci| subChar _ "" = ""
ghci| subChar c (x:xs)
ghci| | c == x = '*' : subChar c xs
ghci| | otherwise = x : subChar c xs
ghci| :}
ghci> subChar 'l' "world"
"wor*d"
ghci>
I want to write a function that returns the longest prefix of a list, where applying a function to every item in that prefix produces a strictly ascending list.
For example:
longestAscendingPrefix (`mod` 5) [1..10] == [1,2,3,4]
longestAscendingPrefix odd [1,4,2,6,8,9,3,2,1] == [1]
longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix _ [] = []
longestAscendingPrefix f (x:xs) = takeWhile (\y z -> f y <= f z) (x:xs)
This code snippet produces the error message in the title. It seems the problem lies within that lambda function.
takeWhile has type takeWhile :: (a -> Bool) -> [a] -> [a]. The first parameter is thus a function that maps an element of the list to a Bool. Your lambda expression has type Ord b => a -> a -> Bool, which does not make much sense.
You can work with explicit recursion with:
longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix f = go
where go [] = []
go [x] = …
go (x1:x2:xs) = …
where you need to fill in the … parts the last one makes a recursive call to go.
So im trying to create this function AgregarMon that basically adds a "Monomio" to "Polinomio"
Monomio would end up being an element inside Polinomio which is a list. You are going to understand better in a little bit
type Monomio = (Int, Int)
type Polinomio = [Monomio]
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon = \m p -> case m of{ (0,0) -> p;
x -> case p of{[] -> [x];
y:ys -> case (snd x == snd y) of { true -> case ((fst x + fst y)==0) of { true -> ys;
false -> (fst x + fst y , snd x):ys;}
false -> case snd x < snd y of{true -> y: agregarMon x ys;
false -> x:y:ys;}}}}
I've been looking at my code like an hour, and i cant find the problem. The error says:
Polinomios.hs:45:140: error:
Unexpected case expression in function application:
case ((fst x + fst y) == 0) of
true -> ys
false -> (fst x + fst y, snd x) : ys
You could write it with parentheses
Or perhaps you meant to enable BlockArguments?
|
45 | y:ys -> case (snd x == snd y) of { true -> case ((fst x + fst y)==0) of { true -> ys; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
Line 45 is the fourth line on the code from above. Im sorry if im missing info, please let me now.
Just in case, someone doesnt knows, fst and snd are on the Prelude. fst takes the first element from a "Monomio" snd the second one. fst = (a,b)->a snd (a,b) -> b
case (snd x == snd y) of { true ->
is wrong: true here is just a variable name, unrelated to the constructor True (with a capital T!). The snippet above is therefore equivalent to
case (snd x == snd y) of { x ->
Hence, the pattern matches any boolean value, True and False. For that reason the other branch false -> ... will never be considered.
I recommend you turn on warnings, since doing so makes GHC report the second branch as redundant code. The fact that the compiler considers a branch useless signals that something is very wrong with the code.
As a final note, in my experience code like
case something of
True -> a
False -> b
is not common, since we can write it as
if something
then a
else b
which is easier to read, in my view.
While you can, in a pinch, use curly brackets and semicolons, Haskell isn't a C-based language. It idiomatically uses indentation to indicate function scope.
Something like this would be more idiomatic:
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon = \m p -> case m of
(0,0) -> p
x -> case p of
[] -> [x]
y:ys -> case (snd x == snd y) of
true -> case ((fst x + fst y)==0) of
true -> ys
false -> (fst x + fst y , snd x):ys
false -> case snd x < snd y of
true -> y: agregarMon x ys
false -> x:y:ys
This compiles (although with warnings, see below), but I don't know if it does what you want it to do. The OP code doesn't compile, so clearly something that does compile isn't equivalent.
All I did, however, was to remove all the curly brackets and semicolons, and instead 'fix' the indentation.
The code is still, in my opinion, too indented, but at least (with one exception) it stays left of 80 characters. Wide code could force people to scroll horizontally, which isn't going to make you many friends.
The above code loads in GHCi, but with warnings:
[1 of 1] Compiling Q58986486 ( 58986486.hs, interpreted )
58986486.hs:14:49: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: false -> ...
|
14 | false -> (fst x + fst y , snd x):ys
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58986486.hs:15:39: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: false -> ...
|
15 | false -> case snd x < snd y of
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
58986486.hs:17:49: warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: false -> ...
|
17 | false -> x:y:ys
| ^^^^^^^^^^^^^^^
Ok, one module loaded.
Thus, I'm not sure that it works as intended.
The version of Mark Seemann can be improved though.
Firstly, let's make m and p actual arguments of agregarMon:
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon m p = case m of
(0,0) -> p
x -> case p of
[] -> [x]
y:ys -> case (snd x == snd y) of
true -> case ((fst x + fst y)==0) of
true -> ys
false -> (fst x + fst y , snd x):ys
false -> case snd x < snd y of
true -> y: agregarMon x ys
false -> x:y:ys
Now we can use pattern matching on agruments to simplify code:
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon (0, 0) p = p
agregarMon x [] = [x]
agregarMon (f, s) (y:ys) = case (snd x == snd y) of
true -> case ((fst x + fst y)==0) of
true -> ys
false -> (fst x + fst y , snd x):ys
false -> case snd x < snd y of
true -> y: agregarMon x ys
false -> x:y:ys
It is not so idiomatic to pattern-match with case a result of condition check, better use if or guards:
agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon (0, 0) p = p
agregarMon x [] = [x]
agregarMon x#(coefx, powx) (y#(coefy, powy):ys)
| powx == powy = if coefx + coefy == 0
then ys
else (coefx + coefy, powx):ys
| powx < powy = y:agregarMon x ys
| otherwise = x:y:ys
Now we have some simple cases and a complex one, but even the complex one is not so hard to read and understand (I even made an assumption that you're working with polynomials, coefficients and powers).
You can run it there: https://repl.it/#Yuri12358/so-monomio-polinomio
Maybe this link will help you to improve your understanding of different ways to make branching in your code: http://learnyouahaskell.com/syntax-in-functions#pattern-matching
I have this code:
esprimo :: Int->Bool
esPrimo x = if length (div x x) == 2 then True else False
But I pulled the error is above
In addition to what sibi said, I think what you are trying to do is this:
isPrime :: Int -> Bool
isPrime x = if length [d | d <- [1..x], x `mod` d == 0] == 2 then True else False
this is basically the direct translation of the mathematical concept of beeing prime into Haskell.
As you don't need the if as it checks the same == already returns a bit more readable might be:
isPrime :: Int -> Bool
isPrime x = length divisors == 2
where divisors = [d | d <- [1..x], x `isMultipleOf` d]
isMultipleOf m n = m `mod` n == 0
Please note that this is of course not the most performant prime-test.
The exact reason for your error is because of the different cases you have used in the type signature and the type definition:
esprimo :: Int -> Bool -- p should be capital here to work.
esPrimo x = if length (div x x) == 2 then True else False
Haskell is case sensitive, so esprimo and esPrimo are different. That being said there is other type error in your code: the type of div is div :: Integral a => a -> a -> a, so it returns a and you are applying length function on it. But length function only accepts list i.e [a] and not a which will produce you type error.