I need help to fix this Haskell function using pattern matching. It should only return true if every formula in the list of formulas is True. Here is what I have so far:
eval_list :: [Formula] -> Bool
eval_list (f:fx) = (eval_list f) && (eval_list fx)
here is how Formula is defined:
data Formula = And Formula Formula
| Not Formula
| Con Bool
deriving Show
You forgot to implement the case for an empty list. Since you each time recurse with a list item that is one item shorter than the previous call, eventually you will make a recursive call with an empty list.
Another problem is that you call eval_list f, but f is the first item of your list and thus a Formula object, not a list of Formulas. You likely should use a eval_formula to evaluate the formula.
You thus can implement this with:
eval_list :: [Formula] -> Bool
eval_list [] = True
eval_list (f:fx) = eval_formula f && eval_list fx
where you will have to implement eval_formula yourself.
You do not need to use explicit recursion. You can for example work with all :: Foldable f => (a -> Bool) -> f a -> Bool:
eval_list :: Foldable f => f Formula -> Bool
eval_list = all eval_formula
In order to evaluate a single Formula, you can use recursion, the function thus will look like:
eval_formula :: Formula -> Bool
eval_formula (And f1 f2) = …
eval_formula (Not f) = …
eval_formula (Con b) = …
where I leave implement the … parts as an exercise.
Related
I am having trouble writing a function which deletes an element from a list within a tuple.
The problem is, I would like the function to return the tuple. However, using the delete function from Data.List gives me a list.
Code:
-- type Value = Int
type Cell = (Int, [Int])
type Board = [Cell]
----------- your solution goes here --------------
-- solvem :: Board -> Board
-- solvem bd = ???
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate cand c1 = delete cand (snd c1) -- This gives me trouble
updateNeighbors :: Cell -> Cell -> Cell
updateNeighbors c1 c2 | isNeighbor c1 c2 = deleteCandidate (head (snd c1)) c2
| otherwise = c2
Since data in Haskell is immutable, how would I return a tuple in deleteCandidate function? Would I have to reconstruct a Cell?
Simply pattern-match the tuple to extract the two pieces, operate on one of them, and then put it back together into a new tuple:
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate cand (x, xs) = (x, delete cand xs)
Alternatively, since (a,) has a Functor instance, you could write
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate cand = fmap (delete cand)
Or, shorter still, you could elide the explicit cand argument as well, and express deleteCandidate as a simple function composition:
deleteCandidate :: Int -> Cell -> Cell
deleteCandidate = fmap . delete
Personally I like the second version best, because I find it hard to think about how this composition works, and how it's different from (fmap delete).
I came across this very old sudoku code which seems greek to me coz of mainly this ugly type
type T = (Int,Int) -> [Int]
To understand this function for instance
mark :: ((Int,Int),Int) -> T -> T
mark (p#(i,j),n) s q#(x,y) =
if p==q then [n] else
if x==i || y==j || e x i && e y j then delete n $ s q else s q
where e a b = div (a-1) 3==div (b-1) 3
I can replace the T with the actual type
mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]
mark (p#(i,j),n) s q#(x,y) =
Now the type arguments don't seem to line up properly. p matches perfectly, but i get confused with "s". If I jump into the call for mark it's like this.....here the list I can easily see it's array of key value pairs with keys like (1,2) etc. These have been filtered for blanks or zeros in sudoku.
input :: String -> (Int,Int) -> [Int]
input s = foldr mark (const [1..9]) $
[(p,n) | (p,n) <- zip idx $ map read $ lines s >>= words, n>0]
The mark function is called with this list and accumulator which is a function (const [1..9]). This doesn't fit the type signature.
mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]
Problem with the code is that I can't see the actual result of the mark function which I still don't understand. When it's passed to a third function it gets some output. Any explanation on how to understand this sphagetti code?
A value of this type
type T = (Int,Int) -> [Int]
maps the coordinates of any sudoku cell (x,y) :: (Int,Int) into a set of the possible values such cell might have (represented as a list of digits [Int]).
The function const [0..9] maps any cell into the set of all digits. It acts as the initial state for a sudoku solver: at the beginning, assume any cell may have any digit.
I'd like to define a function whose parameter takes in a list and an operator. This is what I currently have. I'm trying to define a higher order function that can find the minimum or the maximum.
largest :: (a -> a -> Bool) -> a
largest = findType (>)
findType :: (a -> a -> Bool) -> [a] -> a
findType op [] = error "empty list"
findType op [x] = x
findType op (x:xs)
| x op maxTail = x
| otherwise = maxTail
where maxTail = findType op xs
However, it's not currently working.
You can either write a function that accepts any a -> a -> Bool function parameter, or use the fact that comparable data types implement Ord class.
Here is a piece of code showing both methods to check if a list is sorted
option1 :: (a->a->Bool) -> [a] -> Bool
option1 op (a:b:ls) = op a b && option1 op (b:ls)
option1 op _ = True
option2 :: (Ord a) => Ordering -> [a] -> Bool
option2 op (a:b:ls) = compare a b == op && option2 op (b:ls)
option2 op _ = True
main = do
let ls = [1, 2, 3]
print $ option1 (<) ls
print $ option2 LT ls
Note that the 2nd method requires the use of Ordering data type which only has values LT, EQ and GT (meaning <, = and > respectively). You could make it more flexible by passing, say, a list of acceptable Ordering values or some other data structure, however, in most cases 1st option is more appropriate.
Your code as two different problems. Let's address the one generating the compiler error first.
You gave to findType the following signature:
findType :: (a -> a -> Bool) -> [a] -> a
the intent being to extract from the list given as the second parameter the bound as dictated by the ordering predicate provided as the first parameter.
However, in the last line of the very findType function definition, you bind maxTail to the expression findType xs, which omits the predicate.
The correct line is of course:
where maxTail = findType op xs
Your second error is related to the signature of the largest function, but I will let you find out exactly what it is.
GHC doesn't know that you want to use the function op as an operator into your code, you must tell him, but how can you do that ?
Let's consider the elem function, this function take a value and a list and return True or False depending if the value is present into the list or not.
elem :: Eq a => a -> [a] -> Bool
elem 2 [1,2,3] => True
Basically it's see as a function, and if you want to use them as an operator which can be really useful, you must enclose it with `.
2 `elem` [1,2,3] => True
If you add the remarks of didierc on the call of findType into the where clause, you'll have a working code.
Anyway, It's a very bad idea to put a recursive call into a guard, the code is hardest to read, and I'm not sure be it could lead to performance issue. You need to learn how to use an accumulator, take a look on this
Note
Conversely when a function is considered by default as an operator, to use it as a function just enclose it with ().
2 : [] => [2]
(:) 2 [] => [2]
isTogether' :: String -> Bool
isTogether' (x:xs) = isTogether (head xs) (head (tail xs))
For the above code, I want to go through every character in the string. I am not allowed to use recursion.
isTogether' (x:xs) = isTogether (head xs) (head (tail xs))
If I've got it right, you are interested in getting consequential char pairs from some string. So, for example, for abcd you need to test (a,b), (b,c), (c,d) with some (Char,Char) -> Bool or Char -> Char -> Bool function.
Zip could be helpful here:
> let x = "abcd"
> let pairs = zip x (tail x)
it :: [(Char, Char)]
And for some f :: Char -> Char -> Bool function we can get uncurry f :: (Char, Char) -> Bool.
And then it's easy to get [Bool] value of results with map (uncurry f) pairs :: [Bool].
In Haskell, a String is just a list of characters ([Char]). Thus, all of the normal higher-order list functions like map work on strings. So you can use whichever higher-order function is most applicable to your problem.
Note that these functions themselves are defined recursively; in fact, there is no way to go through the entire list in Haskell without either recursing explicitly or using a function that directly or indirectly recurses.
To do this without recursion, you will need to use a higher order function or a list comprehension. I don't understand what you're trying to accomplish so I can only give generic advice. You probably will want one of these:
map :: (a -> b) -> [a] -> [b]
Map converts a list of one type into another. Using map lets you perform the same action on every element of the list, given a function that operates on the kinds of things you have in the list.
filter :: (a -> Bool) -> [a] -> [a]
Filter takes a list and a predicate, and gives you a new list with only the elements that satisfy the predicate. Just with these two tools, you can do some pretty interesting things:
import Data.Char
map toUpper (filter isLower "A quick test") -- => "QUICKTEST"
Then you have folds of various sorts. A fold is really a generic higher order function for doing recursion on some type, so using it takes a bit of getting used to, but you can accomplish pretty much any recursive function on a list with a fold instead. The basic type of foldr looks like this:
foldr :: (a -> b -> b) -> b -> [a] -> b
It takes three arguments: an inductive step, a base case and a value you want to fold. Or, in less mathematical terms, you could think of it as taking an initial state, a function to take the next item and the previous state to produce the next state, and the list of values. It then returns the final state it arrived at. You can do some pretty surprising things with fold, but let's say you want to detect if a list has a run of two or more of the same item. This would be hard to express with map and filter (impossible?), but it's easy with recursion:
hasTwins :: (Eq a) => [a] -> Bool
hasTwins (x:y:xs) | x == y = True
hasTwins (x:y:xs) | otherwise = hasTwins (y:xs)
hasTwins _ = False
Well, you can express this with a fold like so:
hasTwins :: (Eq a) => [a] -> Bool
hasTwins (x:xs) = snd $ foldr step (x, False) xs
where
step x (prev, seenTwins) = (x, prev == x || seenTwins)
So my "state" in this fold is the previous value and whether we've already seen a pair of identical values. The function has no explicit recursion, but my step function passes the current x value along to the next invocation through the state as the previous value. But you don't have to be happy with the last state you have; this function takes the second value out of the state and returns that as the overall return value—which is the boolean whether or not we've seen two identical values next to each other.
I have 2 Question about 2 haskell functions
flipSymbol :: Model -> Atom -> Model This function must take a Model and an Atom and flip the truth value of the atom in the model. Now I was thinking of writing this function like this:...
flipSymbol m a = map f m
where
f (atom, value) = if a == atom then (atom, not value) else (atom, value)
Is there a better way?
The second one is a something more complicated and I need some help with it if possible..
In order to check the satisfiability of a formula in a given model we propagate the effects of assigning a truth value to an atom in a formula. Assume an atom to which we assign the value True. The following effects
can be applied to the formula:
The positive literals have the same True value and, therefore, any clauses that contain them are removed from the formula. This is to indicate that these clauses could be satisfied and hence no longer affect the satisfiability of the formula.
The negated literals have a value of False and are, therefore, removed from any clause they are in. This is to indicate that these clauses are still not satisfied and can only be made true by one of the other literals obtaining a value of True. In the case where False is assigned to the atom, the positive literals will now be false and should be removed
from their clauses while the negative literals will become true and have their clauses removed from the formula.
For example, in the formula (P _ Q _ R) ^ (:P _ Q _ :R) ^ (P _ :Q), assume we assign True to P. Then the clauses containing P, ie. (P _ Q _ R) and (P _ :Q) are removed from the formula, whereas :P is removed from any clause it is in, ie. (:P _ Q _ :R). This results in the formula (Q _ :R). On the other hand, if we assign False to P, we then remove (:P _ Q _ :R) from the formula and P from its clauses, thus obtaining (Q _ R) ^ (:Q).
The overall formula is satisfiable if it can be reduced to the empty list since in this case all the clauses were satisfied. If there is an empty list within the overall formula then that means that a clause was not satisfied and hence the formula can not be satisfied with the assignment that led to this state.
assign :: (Atom,Bool) -> Formula -> Formula The assign function should take an (Atom,Bool) pair and a formula and propagate the effects of assigning the given truth value to the atom in the formula as described above.
The code(on which I received help from here also):
module Algorithm where
import System.Random
import Data.Maybe
import Data.List
type Atom = String
type Literal = (Bool,Atom)
type Clause = [Literal]
type Formula = [Clause]
type Model = [(Atom, Bool)]
type Node = (Formula, ([Atom], Model))
-- This function takess a Clause and return the set of Atoms of that Clause.
atomsClause :: Clause -> [Atom]
atomsClause = undefined
-- This function takes a Formula returns the set of Atoms of a Formula
atoms :: Formula -> [Atom]
atoms = nub . map snd
-- This function returns True if the given Literal can be found within
-- the Clause.
isLiteral :: Literal -> Clause -> Bool
isLiteral = isLiteral = any . (==)
-- this function takes a Model and an Atom and flip the truthvalue of
-- the atom in the model
flipSymbol :: Model -> Atom -> Model -- is this ok?
flipSymbol m a = map f m where
f (atom, value) = if a == atom
then (atom, not value)
else (atom, value)
assign :: (Atom,Bool) -> Formula -> Formula
assign = undefined --any advice here?
At a glance, I can't see any way to improve your first formula, maybe you may use logical functions instead of a if-then-else, it's faster:
flipSymbol m a = map f m where
f (atom, value) = (atom, value /= (a == atom))
Notice: /= for Bool is basically xor.
To your last question:
The basic idea is to compare the Atoms, incorporate the Bool-values and fiddeling around with logical ops to get your result. Basically, it looks like this:
assign :: (Atom,Bool) -> Formula -> Formula
assign (a,b) = map . (map f) where
f (x,b) = (x,(x==a)&&b)