why is this function non exhaustive? - haskell

Compiler warns the function "insert" is non-exhaustive in the following code:
data Set a = Empty | Set a (Set a) (Set a) deriving (Eq, Show)
insert :: (Ord a) => a -> Set a -> Set a
insert x Empty = Set x Empty Empty
insert x (Set v l r)
| x <= v = Set v (insert x l) r
| v < x = Set v l (insert x r)
-- | otherwise = Set x Empty Empty
main :: IO ()
main = do
let x = insert (5::Int) Empty
print x
GHC reports this
test.hs:4:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘insert’: Patterns not matched: _ (Set _ _ _)
If I uncomment the last line (it's commented out now) in the function, GHC does not report any warning. So I guess GHC thinks the guards are non-exhaustive. But why? If x and v are instances of Ord, then I guess
(x <= v) and (v < x) are all the possible outcomes of comparison?

What if I define this instance:
newtype Fuzzy = Fuzzy Double
instance Eq Fuzzy where
Fuzzy a == Fuzzy b = abs (a-b) < 0.1
instance Ord Fuzzy where
Fuzzy a < Fuzzy b = a < b-0.1
Fuzzy a <= Fuzzy b = a <= b
Then for e.g. v = Fuzzy 0, x = Fuzzy 0.1, you have (x <= v) = (0.1 <= 0) which is false, but (v < x) = (0 < 0) which is also false. Hence both of your guards will fail.
This isn't so hypothetical, in fact Double itself already has such behaviour in degenerate values:
Prelude> sqrt (-1) < 0
False
Prelude> 0 <= sqrt (-1)
False
Now, it's very debatable whether these are really good, even well-formed Ord instances, but at any rate the compiler can't guarantee something like that won't happen. Hence it also can't make the assumption that not (x <= v) implies v < x, so what should happen if neither is fulfilled?
The usual thing to do if you assume all Ord instances you received are docile is to just make the second clause already catch-all:
insert x (Set v l r)
| x <= v = Set v (insert x l) r
| otherwise = Set v l (insert x r)
However, depending on your philosophy, your original code might actually be better. With the catch-all in the second, you just defer the weirdness if someone hands you NaN values. This makes it all the more difficult to understand what's going on.
If tend to deliberately not complete patterns with “impossible cases” in experimental code: this way I'll at least always get a clear runtime error telling me at which point in the code things go awry. Once the code essentially works and you want to make it production-ready, you can then toss in -Wall and learn about all spots where you'd better add some explicit handling of pathological behaviour like the one I mentioned.

Related

Why does matching this function parameter seprately work, but not with guards. (Haskell)

So, I have been trying to use SDL to make a simple GUI. This is so that I start to understand how to use haskell. In this case, I was using https://github.com/palf/haskell-sdl2-examples/blob/master/examples/lesson04/src/Lesson04.hs as reference.
Pay attention, in particular to payloadToIntent on line 72.
payloadToIntent :: SDL.EventPayload -> Intent
payloadToIntent SDL.QuitEvent = Quit
payloadToIntent (SDL.KeyboardEvent k) = getKey k
payloadToIntent _ = Idle
This works perfectly. However, when I change the code to the following, it produces an error. Why does it happen, as to my (admittedtly novice) eyes, this looks equivalent.
payloadToIntent e
| e == SDL.QuitEvent = Quit
| e == SDL.KeyboardEvent k = getKey SDL.KeyboardEvent k
| otherwise = Idle
Error:
src/Events/Intent.hs:15:28: error:
Variable not in scope: k :: SDL.KeyboardEventData
|
15 | | e == SDL.KeyboardEvent k = getKey SDL.KeyboardEvent
| ^
I am using these language extensions: OverloadedStrings, GADTs, PatternGuards
So why did this happen? How could I fix this? Which one would be more idiomatic haskell?
(==) is a function that takes two values of the same type and compares them for equality, returning a Bool. SDL.KeyboardEvent k is not a value of any type (since k is unbound), so you can't compare it with (==).
The idiomatic "choice" is the one that works, i.e. pattern matching. If you want something that has a similar appearance, you can pattern match with case...of instead:
payloadToIntent e = case e of
SDL.QuitEvent -> Quit
SDL.KeyboardEvent k -> getKey k
_ -> Idle
The key idea here is: patterns define variables, bringing them into scope, while expressions do not, requiring all the variables in them to be already defined.
The guard e == SDL.KeyboardEvent k is a boolean valued expression, not a pattern. This is calling function (==) with two arguments: e and SDL.KeyboardEvent k. Your definition, to the compiler, looks like:
payloadToIntent e
| isEqual e SDL.QuitEvent = Quit
| isEqual e (SDL.KeyboardEvent k) = getKey SDL.KeyboardEvent k
| otherwise = Idle
The compiler can not call the equality-test function without passing it the arguments. For that, it needs variable k to be in scope, i.e., to be defined somewhere else.
To stress the point, consider this non-working code:
isSquare :: Int -> String
isSquare n | n == m*m = "It's the square of " ++ show m
| otherwise = "It isn't a square"
This would magically invert the squaring, if possible. That is, however, asking too much to the compiler, which won't magically solve the equation for us. (Indeed, the solution could even fail to be unique!)
As an even more cumbersome case:
f x | x == F y || x == G z = ...
Even if this worked, can we use y or z in the final ...? Probably not. Why should then this be allowed?
Finally, note that, even in those cases where it could work, allowing expressions guards to define variables could be a bad idea. Consider this:
c :: Int
c = 7
f x | x == F c = "Hi"
| otherwise = "there"
Now, is the c in F c a new local variable which is defined on the spot, or is it the constant 7 defined above? If we call f (F 6) do we get Hi (c was a new variable) or there (c was 7)?
Pattern matching avoids this issue by requiring a distinct syntax.

Is it possible to generalise equations in Haskell?

Apologies for my poor wording of the question. I've tried searching for an answer but not knowing what to search is making it very difficult to find one.
Here is a simple function which calculates the area of a triangle.
triangleArea :: Float -> Float -> Float -> Float
triangleArea a b c
| (a + b) <= c = error "Not a triangle!"
| (a + c) <= b = error "Not a triangle!"
| (b + c) <= a = error "Not a triangle!"
| otherwise = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2
Three lines of the function have been taken up for the purposes of error checking. I was wondering if these three lines could be condensed into one generic line.
I was wondering if something similar to the following would be possible
(arg1 + arg2) == arg3
where Haskell knows to check each possible combination of the three arguments.
I think #behzad.nouri's comment is the best. Sometimes doing a little math is the best way to program. Here's a somewhat overdone expansion on #melpomene's solution, which I thought would be fun to share. Let's write a function similar to permutations but that computes combinations:
import Control.Arrow (first, second)
-- choose n xs returns a list of tuples, the first component of each having
-- n elements and the second component having the rest, in all combinations
-- (ignoring order within the lists). N.B. this would be faster if implemented
-- using a DList.
choose :: Int -> [a] -> [([a],[a])]
choose 0 xs = [([], xs)]
choose _ [] = []
choose n (x:xs) =
map (first (x:)) (choose (n-1) xs) ++
map (second (x:)) (choose n xs)
So..
ghci> choose 2 [1,2,3]
[([1,2],[3]),([1,3],[2]),([2,3],[1])]
Now you can write
triangleArea a b c
| or [ x + y <= z | ([x,y], [z]) <- choose 2 [a,b,c] ] = error ...
This doesn't address the question of how to shorten your error checking code, but you may be able to limit how often you repeat it by defining some new types with invariants. This function needs error checking because you can't trust the user to supply Float triples that make a reasonable triangle, and if you continue to define functions this way then every triangle-related function you write would need similar error checks.
However, if you define a Triangle type, you can check your invariants only once, when a triangle is created, and then all other functions will be guaranteed to receive valid triangles:
module Triangle (Triangle(), mkTriangle, area) where
data Triangle a = Triangle a a a deriving Show
mkTriangle :: (Num a, Ord a) => a -> a -> a -> Either String (Triangle a)
mkTriangle a b c
| a + b <= c = wrong
| a + c <= b = wrong
| b + c <= a = wrong
| otherwise = Right $ Triangle a b c
where wrong = Left "Not a triangle!"
area :: Floating a => Triangle a -> a
area (Triangle a b c) = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2
Here we export the Triangle type, but not its constructor, so that the client must use mkTriangle instead, which can do the required error checking. Then area, and any other triangle functions you write, can omit the checks that they are receiving a valid triangle. This general pattern is called "smart constructors".
Here are two ideas.
Using existing tools, you can generate all the permutations of the arguments and check that they all satisfy a condition. Thus:
import Data.List
triangleArea a b c
| any (\[x, y, z] -> x + y <= z) (permutations [a,b,c])
= error "Not a triangle!"
| otherwise = {- ... -}
This doesn't require writing very much additional code; however, it will search some permutations you don't care about.
Use the usual trick for choosing an element from a list and the left-overs. The zippers function is one I use frequently:
zippers :: [a] -> [([a], a, [a])]
zippers = go [] where
go b [] = []
go b (v:e) = (b, v, e) : go (v:b) e
We can use it to build a function which chooses only appropriate triples of elements:
triples :: [a] -> [(a, a, a)]
triples xs = do
(b1, v1, e1) <- zippers xs
(b2, v2, e2) <- zippers e1
v3 <- b1 ++ b2 ++ e2
return (v1, v2, v3)
Now we can write our guard like in part (1), but it will only consider unique pairings for the addition.
triangleArea a b c
| any (\(x, y, z) -> x + y <= z) (triples [a,b,c])
= error "Not a triangle!"
| otherwise = {- ... -}

Neighborhood of a mathematical expression using Haskell

I'm trying to implement with Haskell an algorithm to manipulate mathematical expressions.
I have this data type :
data Exp = Var String | IVal Int | Add Exp Exp
This will be enough for my question.
Given a set of expression transformations, for example :
(Add a b) => (Add b a)
(Add (Add a b) c) => (Add a (Add b c))
And an expression, for example : x = (Add (Add x y) (Add z t)), I want to find all expressions in the neighborhood of x. Given that neighborhood of x is defined as: y in Neighborhood(x) if y can be reached from x within a single transformation.
I am new to Haskell. I am not even sure Haskell is the right tool for this job.
The final goal is to get a function : equivalent x which returns a set of all expressions that are equivalent to x. In other words, the set of all expressions that are in the closure of the neighborhood of x (given a set of transformations).
Right now, I have the following :
import Data.List(nub)
import Data.Set
data Exp = IVal Int
| Scalar String
| Add Exp Exp
deriving (Show, Eq, Ord)
commu (Add a b) = (Add b a)
commu x = x
assoc (Add (Add a b) c) = (Add a (Add b c))
assoc (Add a (Add b c)) = (Add (Add a b) c)
assoc x = x
neighbors x = [commu x, assoc x]
equiv :: [Exp] -> [Exp]
equiv closure
| closure == closureUntilNow = closure
| otherwise = equiv closureUntilNow
where closureUntilNow = nub $ closure ++ concat [neighbors x|x<-closure]
But It's probably slower than needed (nub is O(n^2)) and some terms are missing.
For example, if you have f = (x+y)+z, then, you will not get (x+z)+y, and some others.
Imports, etc. below. I'll be using the multiset package.
import Control.Monad
import Data.MultiSet as M
data Exp = Var String | IVal Int | Add Exp Exp deriving (Eq, Ord, Show, Read)
A bit of paper-and-pencil work shows the following fact: expressions e1 and e2 are in the congruence closure of your relation iff the multiset of leaves are equal. By leaves, I mean the Var and IVal values, e.g. the output of the following function:
leaves :: Exp -> MultiSet Exp
leaves (Add a b) = leaves a `union` leaves b
leaves e = singleton e
So this suggests a nice clean way to generate all the elements in a particular value's neighborhood (without attempting to generate any duplicates in the first place). First, generate the multiset of leaves; then nondeterministically choose a partition of the multiset and recurse. The code to generate partitions might look like this:
partitions :: Ord k => MultiSet k -> [(MultiSet k, MultiSet k)]
partitions = go . toOccurList where
go [] = [(empty, empty)]
go ((k, n):bag) = do
n' <- [0..n]
(left, right) <- go bag
return (insertMany k n' left, insertMany k (n-n') right)
Actually, we only want partitions where both the left and right part are non-empty. But we'll check that after we've generated them all; it's cheap, as there's only two that aren't like that per invocation of partitions. So now we can generate the whole neighborhood in one fell swoop:
neighborhood :: Exp -> [Exp]
neighborhood = go . leaves where
full = guard . not . M.null
go m
| size m == 1 = toList m
| otherwise = do
(leftBag, rightBag) <- partitions m
full leftBag
full rightBag
left <- go leftBag
right <- go rightBag
return (Add left right)
By the way, the reason you're not getting all the terms is because you're generating the reflexive, transitive closure but not the congruence closure: you need to apply your rewrite rules deep in the term, not just at the top level.

Haskell syntax for 'or' in case expressions

In F#, I can use | to group cases when pattern matching. For example,
let rec factorial n =
match n with
| 0 | 1 -> 1 // like in this line
| _ -> n * factorial (n - 1)
What's the Haskell syntax for the same?
There is no way of sharing the same right hand side for different patterns. However, you can usually get around this by using guards instead of patterns, for example with elem.
foo x | x `elem` [A, C, G] = ...
| x `elem` [B, D, E] = ...
| otherwise = ...
with guards:
factorial n
| n < 2 = 1
| otherwise = n * (factorial (n - 1))
with pattern matching:
factorial 0 = 1
factorial 1 = 1
factorial n = n * (factorial (n - 1))
I'm not entirely familiar with F#, but in Haskell, case statements allow you to pattern match, binding variables to parts of an expression.
case listExpr of
(x:y:_) -> x+y
[x] -> x
_ -> 0
In the theoretical case that Haskell allowed the same:
It would therefore be problematic to allow multiple bindings
case listExpr of
(x:y:_) | [z] -> erm...which variables are bound? x and y? or z?
There are rare circumstances where it could work, by using the same binding:
unEither :: Either a a -> a
unEither val = case val of
Left v | Right v -> v
And as in the example you gave, it could work alright if you only match literals and do not bind anything:
case expr of
1 | 0 -> foo
_ -> bar
However:
As far as I know, Haskell does not have syntax like that. It does have guards, though, as mentioned by others.
Also note:
Using | in the case statement serves a different function in Haskell. The statement after the | acts as a guard.
case expr of
[x] | x < 2 -> 2
[x] -> 3
_ -> 4
So if this sort of syntax were to be introduced into Haskell, it would have to use something other than |. I would suggest using , (to whomever might feel like adding this to the Haskell spec.)
unEither val = case val of
Left v, Right v -> v
This currently produces "parse error on input ,"
Building on some of the above answers, you can (at least now) use guards to do multiple cases on a single line:
case name of
x | elem x ["Bob","John","Joe"] -> putStrLn "ok!"
"Frank" -> putStrLn "not ok!"
_ -> putStrLn "bad input!"
So, an input of "Bob", "John", or "Joe" would give you an "ok!", whereas "Frank" would be "not ok!", and everything else would be "bad input!"
Here's a fairly literal translation:
factorial n = case n of
0 -> sharedImpl
1 -> sharedImpl
n -> n * factorial (n - 1)
where
sharedImpl = 1
View patterns could also give you a literal translation.
isZeroOrOne n = case n of
0 -> True
1 -> True
_ -> False
factorial1 n = case n of
(isZeroOrOne -> True) -> 1
n -> n * factorial (n - 1)
factorial2 n = case n of
(\n -> case n of { 0 -> True; 1 -> True; _ -> False }) -> 1
n -> n * factorial (n - 1)
Not saying that these are better than the alternatives. Just pointing them out.

Strange pattern matching with functions instancing Show

So I'm writing a program which returns a procedure for some given arithmetic problem, so I wanted to instance a couple of functions to Show so that I can print the same expression I evaluate when I test. The trouble is that the given code matches (-) to the first line when it should fall to the second.
{-# OPTIONS_GHC -XFlexibleInstances #-}
instance Show (t -> t-> t) where
show (+) = "plus"
show (-) = "minus"
main = print [(+),(-)]
returns
[plus,plus]
Am I just committing a mortal sin printing functions in the first place or is there some way I can get it to match properly?
edit:I realise I am getting the following warning:
Warning: Pattern match(es) are overlapped
In the definition of `show': show - = ...
I still don't know why it overlaps, or how to stop it.
As sepp2k and MtnViewMark said, you can't pattern match on the value of identifiers, only on constructors and, in some cases, implicit equality checks. So, your instance is binding any argument to the identifier, in the process shadowing the external definition of (+). Unfortunately, this means that what you're trying to do won't and can't ever work.
A typical solution to what you want to accomplish is to define an "arithmetic expression" algebraic data type, with an appropriate show instance. Note that you can make your expression type itself an instance of Num, with numeric literals wrapped in a "Literal" constructor, and operations like (+) returning their arguments combined with a constructor for the operation. Here's a quick, incomplete example:
data Expression a = Literal a
| Sum (Expression a) (Expression a)
| Product (Expression a) (Expression a)
deriving (Eq, Ord, Show)
instance (Num a) => Num (Expression a) where
x + y = Sum x y
x * y = Product x y
fromInteger x = Literal (fromInteger x)
evaluate (Literal x) = x
evaluate (Sum x y) = evaluate x + evaluate y
evaluate (Product x y) = evaluate x * evaluate y
integer :: Integer
integer = (1 + 2) * 3 + 4
expr :: Expression Integer
expr = (1 + 2) * 3 + 4
Trying it out in GHCi:
> integer
13
> evaluate expr
13
> expr
Sum (Product (Sum (Literal 1) (Literal 2)) (Literal 3)) (Literal 4)
Here's a way to think about this. Consider:
answer = 42
magic = 3
specialName :: Int -> String
specialName answer = "the answer to the ultimate question"
specialName magic = "the magic number"
specialName x = "just plain ol' " ++ show x
Can you see why this won't work? answer in the pattern match is a variable, distinct from answer at the outer scope. So instead, you'd have to write this like:
answer = 42
magic = 3
specialName :: Int -> String
specialName x | x == answer = "the answer to the ultimate question"
specialName x | x == magic = "the magic number"
specialName x = "just plain ol' " ++ show x
In fact, this is just what is going on when you write constants in a pattern. That is:
digitName :: Bool -> String
digitName 0 = "zero"
digitName 1 = "one"
digitName _ = "math is hard"
gets converted by the compiler to something equivalent to:
digitName :: Bool -> String
digitName x | x == 0 = "zero"
digitName x | x == 1 = "one"
digitName _ = "math is hard"
Since you want to match against the function bound to (+) rather than just bind anything to the symbol (+), you'd need to write your code as:
instance Show (t -> t-> t) where
show f | f == (+) = "plus"
show f | f == (-) = "minus"
But, this would require that functions were comparable for equality. And that is an undecidable problem in general.
You might counter that you are just asking the run-time system to compare function pointers, but at the language level, the Haskell programmer doesn't have access to pointers. In other words, you can't manipulate references to values in Haskell(*), only values themselves. This is the purity of Haskell, and gains referential transparency.
(*) MVars and other such objects in the IO monad are another matter, but their existence doesn't invalidate the point.
It overlaps because it treats (+) simply as a variable, meaning on the RHS the identifier + will be bound to the function you called show on.
There is no way to pattern match on functions the way you want.
Solved it myself with a mega hack.
instance (Num t) => Show (t -> t-> t) where
show op =
case (op 6 2) of
8 -> "plus"
4 -> "minus"
12 -> "times"
3 -> "divided"

Resources