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
| ^^^^^^^^^^
Related
With a case _ of syntax like this:
fun a b c =
case (a, b, c) of
(Just True, Just _, _) -> foo
(Just True, _, Just _) -> foo
_ -> bar
Can I merge the first two conditions and avoid repeating foo?
Alternatively, is there any other (cleaner) way to express that I want to run foo if and only if a is Just True and either b or c are not Nothing?
You can do something like this:
fun a b c = case (a, b <|> c) of
(Just True, Just _) -> foo
_ -> bar
Of course, that's just hiding the extra match in (<|>), but you gotta pay the piper some time.
If b and c do not have the same type, you can cause them to with the ill-named void.
Let me complement the other answers with a "boring" alternative:
fun a b c = let
foo' = foo
in case (a, b, c) of
(Just True, Just _, _) -> foo'
(Just True, _, Just _) -> foo'
_ -> bar
This might or might not answer the intended question, depending on the actual goal.
If the goal was to avoid writing two patterns in the case, this of course fails to meet the goal.
If instead the goal was to avoid repeating foo, which could be a very long expression (e.g., a long do block in some monad), this meets the goal by giving a short name to the long expression.
Don't know if this looks cleaner but you could use the good old pal if too:
fun a b c =
if a == Just True && (isJust b || isJust c)
then foo
else bar
or use guards
fun a b c =
case a of
Just True | isJust b || isJust c -> foo
_ -> bar
without case:
fun (Just True) b c | isJust b || isJust c = foo
fun _ _ _ = bar
all is using isJust and as Daniel pointed out those too will give the piper it's due (pattern match).
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.
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
Suppose I have a data type
data Foo = Foo String Bool | Bar (String->Bool)
I want a function f that does:
f (Foo _ _) = [String, Bool]
f (Bar _) = [String->Bool]
In particular, I'd like this function to magically know that Foo and Boo are constructors, and not give me either of
f (Foo _ _) = [String -> Bool] -- #Don't want this!!!!
f (Boo _) = [String, Bool] -- #Don't want this!!!!
How can I do this? I know that I can print a list of records of an ADT using Data.Data, but I can't figure out how to print a list of typenames.
(If this is not possible, I would settle for a function f' that takes in ADTs and outputs whether or not it has 0 parameters.
f'(Foo _ _) = False
f'(Bar _) = False
I want this to work even if I don't assign records to the ADT f' operates on.)
I have a function that outputs a booleanlike property given a datatype. This function calculates the property by pattern matching on the first constructor of the datatype, so something like
data C = C1 | C2 | .. | Cn
f :: C -> Bool
f (C1 _ _ ... _) = True
f (C2 _ _ ... _) = True
f (C3 _ _ ... _) = False
.
.
.
f (Cn _ _ ..._) = False
Is there a more compact way to perform pattern-matching, or is there another (also more compact) way to go about my property checking? I prefer not to add the property to the data type definition since it can be calculated with relative ease.
You can avoid the wildcard patterns using record syntax. Also, use a case expression to avoid having to repeat the function name, e.g.
f :: C -> Bool
f x = case x of
C1 {} -> True
C2 {} -> False
...
Cn {} -> False
That's about as compact as it's going to get without changing your data type.
In addition, just list the Trueones or the False ones, depending on what you have less, and make the majority outcome a default:
f C1{} = True
f C42{} = True
f _ = False -- all others false
You might want to look at toConstr in the Data.Data module. This can give you a representation of the constructor, which you can then analyze as you wish (i.e. convert to a String, or get an index out of).
Building on #yatima's answer, you could do something like this
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Char
import Data.Data
data C = C1 Int
| C2 Int
| C3 Int
| C4 Int
deriving (Data,Typeable)
f :: C -> Bool
f c = let [_,n] = show (toConstr c) in digitToInt n < 3
Then in GHCI
>> f (C1 0)
True
>> f (C2 0)
True
>> f (C3 0)
False
>> f (C4 0)
False
Perhaps:
f (x _ _ ... _) = g x where
g C1 = True
g C2 = True
g C3 = False
.
.
.
g Cn = False
You might be able to save a bit of typing using a case statement instead, but not much.
If we had more detail of the problem you were trying to solve (e.g. is there another representation for your data is there some pattern to the output) perhaps there's another approach.