What does this statement mean in Haskell? - haskell

I'm currently still getting to know more about Haskell, under the topic of Pattern Matching, what does it mean by _ && _ = False in Haskell? I came across this statement in one of the lecture slides, like what does it mean by the underscores? Thanks again!

The underscores are wildcards. That is, they match any value, but do not bind the value to a name. A common example of this usage is:
True && True = True
_ && _ = False

Underscores means a wildcard. It binds with any value. It thus means that for any value for the left and right operand for the given type of the function, it will fire that clause, and thus return False.
One can thus define (&&) :: Bool -> Bool -> Bool with:
(&&) :: Bool -> Bool -> Bool
True && True = True
_ && _ = False
The real implementation of (&&) is however lazy in its second parameter, and is implemented as [src]:
-- | Boolean \"and\"
(&&) :: Bool -> Bool -> Bool
True && x = x
False && _ = False

Related

Using filter with custom datatypes

I have these datatypes:
data Command = Back Int | Front Val deriving (Show,Eq)
data Val = Val {first::Int, second::Int, third::Int} deriving (Show, Eq)
type Program = [Command]
I have this function:
foo :: Program -> Int
foo list = length (filter (==Front Val {first, second, third}) list)
The purpose is to find how many times a Front occurs USING FILTER ONLY, and foo gives compilation error. I am not sure how to represent the integer/val part of Front.
You can not use an equality check (==) :: Eq a => a -> a -> Bool with variables like first and second, if these do not have a value. What you need here is pattern matching.
We can for example use list comprehension:
foo :: Program -> Int
foo list = length [ v | v#(Front _) <- list ]
There is no need to match the parameter with Val {}, or Val _ _ _, etc. since the only data constructor for the Val type is Val.
In case you think you will later add more data constructors, you can however add an extra subpattern:
foo :: Program -> Int
foo list = length [ v | v#(Front (Val {})) <- list ]
Or we can do the pattern matching in a function and use filter :: (a -> Bool) -> [a] -> [a], like:
foo :: Program -> Int
foo = length . filter f
where f (Front _) = True
f _ = False
or if we include the Val data constructor check:
foo :: Program -> Int
foo = length . filter f
where f (Front (Val {})) = True
f _ = False
As #WillemVanOnsem said in his answer, the approach you're using doesn't work. Try using filter (\x -> case x of { Front _ -> True; Back _ -> False }) list. You may be able to work out how this works from that alone, but if you need any more details:
\x -> case x of { Front _ -> True; Back _ -> False } is a lambda expression. It defines an unnamed (or anonymous) function which takes one parameter, named x, and returns the value given by case x of { Front _ -> True; Back _ -> False }.
case x of { Front _ -> True; Back _ -> False } does pattern matching on x. If x is of the form Front _, where _ can be anything, then it returns True; otherwise it returns False. Normally this statement would be formatted like this:
case x of
Front _ -> True
Back _ -> False
But the compact syntax above is shorter and so works better in this case.
The lambda expression above - which as discussed returns True when its argument is of the form Front _ - is then passed to filter as its argument.

Operator & in haskell?

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

How do I transform a pattern on booleans to an if condition?

I'm new to Haskell and I'm trying to transform the pattern matching below to an if condition:
myOr :: Bool -> Bool -> Bool
myOr False False = False
myOr _ _ = True
This is what I came up with, but it doesn't even compile:
myOr2 :: Bool -> Bool -> Bool
myOr2 False False = False
myOr2 _ _ = True
myOr2 If False False Then False Else True
I think I'm doing something wrong here, but what is it?
Something like this?
bool_or x y = if x
then ... -- x is true
else if y
then ... -- y is true
else ... -- both false
Pattern matching is much more readable, anyway.
Exercise: you do not really need the second if y.

Are there any tools for guard analysis?

I'm a Haskell noob and while reading about Implications in Haskell Road I came to following puzzle.
verdict :: Bool -> Bool -> (Bool, String)
verdict p q | not result = (False, "LIAR")
| result && p = (True, "telling the truth")
| result = (True, "innocent unless proven guilty")
| otherwise = (False, "we shouldn't get here")
where result = (not p) || q
-- map (\x -> verdict (fst x == 1) (snd x == 1)) [(1,1),(1,0),(0,1),(0,0)]
Is there a tool that would warn me about the otherwise or other similar logical errors?
I think I would write this function a different way:
-- not result
verdict True False = (False, "LIAR")
-- result && p
verdict True True = (True , "telling the truth")
-- result
verdict False _ = (True , "innocent unless proven guilty")
verdict _ True = (True , "innocent unless proven guilty")
-- otherwise
verdict _ _ = (False, "we shouldn't get here")
Then not only is it obvious to humans which clauses can be left out (the last two), but also to the machine; ghc says this at its default warning level:
test.hs:2:5: Warning:
Pattern match(es) are overlapped
In an equation for ‘verdict’:
verdict _ True = ...
verdict _ _ = ...
Checking guard overlap in general is of course undecidable; and furthermore I don't know of a tool that will try to give an approximate answer.
This is probably a clearer expression of your intent:
implies :: Bool -> Bool -> Bool
p `implies` q = not p || q -- The backticks allow infix usage.
-- The assumption is that p `implies` q is a known fact.
verdict :: Bool -> Bool -> (Bool, String)
verdict p q = (result, remark)
where
result = p `implies` q
remark
| not result = "LIAR"
| p = "telling the truth"
| otherwise = "innocent until proven guilty"
Guards are syntax sugar for pattern matches on Bool values. For general tips on arranging pattern matches, see Daniel Wagner's answer.

Haskell - please help me simplify these two functions

I am trying to work through the exercises in Write Yourself a Scheme in 48 Hours. I need help with simplifying couple of functions.
data LispVal = Number Integer
| String String
| Bool Bool
isNumber :: [LispVal] -> LispVal
isNumber [] = Bool False
isNumber [(Number _)] = Bool True
isNumber ((Number _):xs) = isNumber xs
isNumber _ = Bool False
isString :: [LispVal] -> LispVal
isString [] = Bool False
isString [(String _)] = Bool True
isString ((String _):xs) = isString xs
isString _ = Bool False
The isNumber and isString functions have lot common structure. How do I go about factoring out this common structure?
While you can't parameterize the pattern match itself, you can write yourself small helper functions so you at least don't have to repeat the list handling for every function:
isString (String _) = True
isString _ = False
isNumber (Number _) = True
isNumber _ = False
all1 _ [] = False
all1 f xs = all f xs
isListOfStrings = Bool . all1 isString
isListOfNumbers = Bool . all1 isNumber
In my opinion, the special case handling of the empty list isn't consistent here. You should consider just using all instead (so that the empty list can be a list of any kind, similar to how Haskell's lists work).

Resources