Is it possible to write a contract that checks whether a statement is true?
For example, I want to define a contract
true :: Contract a
such that for all values x, the equation
assert true x == x
holds.
I have tried something like this:
true :: Contract a
true = Pred (\a -> True)
But when running assert true x == x compiler says that x is undefined.
When running assert true 5==6 the result is False, and I have hoped for a Contract violation error.
How should I change this true contract? Would appreciate your help.
Here
data Contract :: * -> * where
Pred :: (a -> Bool) -> Contract a
Fun :: Contract a -> Contract b -> Contract (a -> b)
Assert will cause a run-time failure if a contract is violated, and otherwise return the original result:
assert :: Contract a -> a -> a
assert (Pred p) x = if p x then x else error "contract violation"
assert (Fun pre post) f = assert post . f . assert pre
You can see the problem very clearly if you consider your definitions of true and assert. Here are the relevant parts:
true :: Contract a
true = Pred (\a -> True)
assert :: Contract a -> a -> a
assert (Pred p) x = if p x then x else error "contract violation"
...
Put them together and you see that assert true x will test (\a -> True) x and either produce x or throw an error, depending on if it's True or False. And that this will always be True, no matter what expression you use for x, since the predicate by definition always returns True, and ignores its argument.
The simple fix is to have the true "contract" actually test its argument, like this:
true :: Contract Bool
true = Pred id
That is, this new true can only apply to a value of type Bool (because it really doesn't make sense for any others) and does nothing to it. It lets the value through unchanged if it's True, and otherwise throws the contract violation error you want:
Prelude> assert true (5==6)
*** Exception: contract violation
CallStack (from HasCallStack):
error, called at <interactive>:21:46 in interactive:Ghci2
Prelude> assert true (5==5)
True
And note the parentheses in assert true (5==6), since assert true 5==6 is parsed as (assert true 5)==6, due to function application being the most precedent "operator" in Haskell. assert true 5==6 leads to an error because this corrected version of true only works on a Boolean value, and therefore not on 5.
Note that assert true x == x compares assert true x to x; so assert true 5 is 5 and of course 5 == 6 is false and not a contract violation.
If you intended assert true (x == x) to hold instead, then it seems like
true :: Contract Bool
true = Pred id
assert true (5==6) -- Contract violation
is what you want
"when running assert true x == x compiler says that x is undefined" is rather key here. Your assert call appears to me to be one expression containing two references to x, and the outermost function is (==). Neither side can be evaluated without a binding for x. The assert true x portion never sees ==, and if we rewrote it to assert true (x == x) we'd still need to provide an x :: Eq a. I don't know how to examine a function as such, but there certainly are options I'm not well versed in.
Related
Why does this function always succeed? It always returns True with any values and any types. Is this the correct behavior?
f a b = case a of b -> True; _ -> False
The b in the case definition is not the b in in the head of the f definition. You created a new locally scoped variable. Your code is thus equivalent to:
f a b = case a of
c -> True
_ -> False
Pattern matching with a variable indeed always succeeds.
If you want to check if two values are the same, you will need to define some function (or let Haskell automatically derive Eq for example).
Note: you can turn on the -Wname-shadowing warning to let the compiler warn you about creating identifiers that shadow existing ones. For example your code will produce:
Prelude> f a b = case a of b -> True; _ -> False
<interactive>:1:19: warning: [-Wname-shadowing]
This binding for ‘b’ shadows the existing binding
bound at <interactive>:1:5
Just in addition to the perfect answer accepted, my two cents:
this:
f a b = case a of b -> True; _ -> False -- (A)
and this:
f a b = case a of
c -> True
_ -> False --(B)
are is equivalent to:
f a b = case a of
_ -> True
or
f a b = True
or
f _ b = True
So, be careful because that's the real behavior you created, a function that takes two parameters and returns always True.
Also:
(A) and (B) will show this warning if -Woverlapping-patterns is used:
warning: [-Woverlapping-patterns]
Pattern match is redundant
In a case alternative: _ -> ...
|
3 | _ -> False
| ^^^^^^^^^^
How to check the second argument between an operation of true and false in haskell? E.g, False && True will only check the first argument and then will stop the operation. Is there something like False & True in Haskell to check both arguments?
&& in the prelude is implemented as
(&&) :: Bool -> Bool -> Bool
True && x = x
False && _ = False
Which means in the case that the first argument is False the second
one is never evaluated. You could always implement your own version to have the behaviour that you want e.g.:
(.&&.) :: Bool -> Bool -> Bool
True .&&. x = x
False .&&. False = False
False .&&. True = False
In which the second second argument is evaluated in either case.
There is no good reason why you'd want this, but if you insist...
import Control.Parallel (pseq)
(&&!) :: Bool -> Bool -> Bool
a &&! b = b `pseq` (a&&b)
Usually, seq (which doesn't require any imports) will also suffice instead of pseq, but only the latter actually guarantees that b will be evaluated.
Of course, the semantics of this function will be exactly the same as && alone, it will just be slower in some cases.
I was mislead by the OP's subject "Operator & in haskell?"
For those who are here looking for (&) in Haskell
& is a reverse application operator in Data.Function
(&) :: a -> (a -> b) -> b
The following questions appear in a mock exam and i cannot understand how the answers came about.
Anyone care to derive a method of calculating the answer as a similar set of questions will appear in an exam tomorrow.
Match each function definition with the logical operation it implements
Question Correct Match Selected Match
funA x True = x
funA _ _ = False
-- Correct A. Logical AND
funB x False = x
funB x True = not x
-- Correct B. Exclusive OR
funC False _ = True
funC True x = x
-- Correct C. Logical IMPLICATION
funD x False = x
funD _ True = True
-- Correct D. Logical (Inclusive) OR
funE x True = x
funE x False = not x
-- Correct E. Logical EQUIVALENCE
The question is to match logical operations to functions implementing them.
One method is simply comparing the truth table for the logical connectives to
that of the functions.
For instance, AND:
x y x AND y
-----------------
F F F
F T F
T F F
T T T
matches
funA x True = x
funA _ _ = False
as
x y funA x y
-------------------------
F F F
F T x == False
T F F
T T x == True
and similarly for the rest.
Another option is to observe that x AND y is true iff x is true and y is true, and see which function satisfies that.
i have this doubt, and can't find an answer to my problem.
the bit of haskell code that does not want to be compiled :
type Prim = (String,String)
primeiros :: [Prim] -> [String]
primeiros [] = []
primeiros (a:xs) = fst a: primeiros xs
nosPrimeiros :: String -> [Prim] -> Bool
nosPrimeiros x [] = False
nosPrimeiros x ((a,b):xs) = if (x == primeiros (a,b) ) then True
else nosPrimeiros x xs
basically what the first function does is
primeiros [("one","guy"),("yes","man"),("works","not")]
> ["one","yes","works"]
And the second function, checks if string "one" is embed on the first position of each tuple, if it is at least inside one, gives true, if "one" is not in the first position of at least one , gives false.
nosPrimeiros "one" [("one","guy"),("yes","man"),("works","not")]
True
What fails? This is basic Haskell stuff, not being able to do this drives me nuts...
Thank you very much for your help.
if (x == primeiros (a, b) ) should be if (x == a).
I want to include more than one case statement in a Haskell function (see below for an example of a hypothetical function).
However, it is not legal Haskell. What is a better way of accomplishing the same thing? Furthermore, if the case statements are not returning anything, but simply setting some value, why is it not legal to have more than one case statement in a function?
(I would get a "parse error on input `case'" on line 5)
tester x y =
case (x < 0) of
True -> "less than zero."
False -> "greater than or equal to zero."
case (y == "foo")
True -> "the name is foo."
False -> "the name is not foo."
Note that if my function were simply:
tester x y =
case (x < 0) of
True -> "less than zero."
False -> "greater than or equal to zero."
...then it would compile.
In general the body of a function has to be a single expression (very often made up of smaller expressions). The following isn't allowed, for example:
f x y =
"foo"
"bar"
This is equivalent to your first example—we've just substituted one kind of expression (string literals) for another (your case expressions).
It's certainly possible to include more than one case expression in a Haskell function:
tester :: Int -> String -> (String, String)
tester x y = (a, b)
where
a = case (x < 0) of
True -> "less than zero."
False -> "greater than or equal to zero."
b = case (y == "foo") of
True -> "the name is foo."
False -> "the name is not foo."
Or even:
tester :: Int -> String -> IO ()
tester x y = do
putStrLn $ case (x < 0) of
True -> "less than zero."
False -> "greater than or equal to zero."
putStrLn $ case (y == "foo") of
True -> "the name is foo."
False -> "the name is not foo."
These work because the body of the function is a single expression (although neither is really idiomatic Haskell).
I wouldn't use a case statement in this case though, this IMO looks better:
tester :: Int -> String -> String
tester x y | x < 0 = "less than zero. " ++ expr
| otherwise = "greater than or equal to zero. " ++ expr
where expr = if y == "foo" then "the name is foo." else "the name is not foo."
In general, it looks like what you want is guards. However, as already mentioned, your function is not a single expression. Assuming that you want to return a tuple of strings, it can be written like this using guards (and some added fun from Arrows):
import Control.Arrow
testx x | x < 0 = "Less then zero."
| otherwise = "Greater then or equal to zero."
testy y | y == "foo" = "The name is foo."
| otherwise = "The name is not foo."
tester = curry (testx *** testy)
You could also drop the Control.Arrow bit all together and write:
tester x y = (testx x, testy y)