Related
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.
I am new to Haskell and I am trying to calculate the maximum segment sum,
(#) :: Int -> Int -> Int
x # y = 0 `max` (x + y)
mss2 :: [Int] -> Int
mss2 = maximum . scanr (#) 0
The error is
No Modules Loaded for (#)
I found this snippet in Richard Bird's text.
What am I missing here?
Are there other ways to declare/overload the operators, is my approach wrong?
It appears that in the context of that book, (#) is being used as a stand-in for some binary operator such as (+) or (<>), even though this is not actually legal Haskell syntax†.
For questions about Haskell syntax, it’s helpful to consult the Haskell 2010 Report.
In Ch. 2 Lexical Structure, under §2.2 Lexical Program Structure, you can find # in the grammar of symbols that may appear in an operator name:
symbol → ascSymbol | uniSymbol⟨special | _ | " | '⟩
ascSymbol → ! | # | $ | % | & | ⋆ | + | . | / | < | = | > | ? | #
| \ | ^ | | | - | ~ | :
And §2.4 Lexical Structure: Identifiers and Operators defines valid operator names to include such symbols:
varsym → ( symbol⟨:⟩ {symbol} )⟨reservedop | dashes⟩
consym → ( : {symbol} )⟨reservedop⟩
However, the subscript in angle brackets denotes a “difference” or exclusion, so this disallows a list of reserved identifiers. Under the production reservedop you can find that # appears in that list:
reservedop → .. | : | :: | = | \ | | | <- | -> | # | ~ | =>
The reason is that the # symbol denotes an “as” pattern, described in §3.17.2.8 Informal Semantics of Pattern Matching:
Matching an as-pattern var#apat against a value v is the result of matching apat against v, augmented with the binding of var to v.
As patterns are very useful for controlling the sharing of values and making certain definitions more concise, e.g.:
-- | Merge two sorted lists.
merge :: (Ord a) => [a] -> [a] -> [a]
-- ‘as0’ & ‘bs0’ denote the original input lists.
-- ‘as’ & ‘bs’ denote their tails.
merge as0#(a : as) bs0#(b : bs) = case compare a b of
-- ‘as0’ passes along the same list cell;
-- repeating ‘a : as’ would allocate a /new/ cell.
GT -> b : merge as0 bs
_ -> a : merge as bs0
merge [] bs0 = bs0
merge as0 [] = as0
Therefore, the definition:
x # y = 0 `max` (x + y)
Or more conventionally written x#y = …, is equivalent to defining two variables referring to the same value, which furthermore is defined recursively:
x = 0 `max` (x + y)
y = x
Without the type signature Int -> Int -> Int, this definition would be accepted, defining x, y :: (Ord a, Num a) => a, but attempting to evaluate either variable would produce an infinite loop, since this is “unproductive” recursion.
The solution is to use a non-reserved symbol as your operator name instead, such as <#> or +..
† I can’t find a citation for this, but it’s possible that GHC used to accept this syntax, even though it was also disallowed by the Haskell 98 Report which was current at the time the first edition of this book came out, and that this example code just wasn’t updated for the second edition.
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.
ltl p {(Xq) || (Fp)},
what will be the formal language accepted of this LTL formula?
For example :
ltl p { p && (Xq)}
{w = a0a1a2.... | p∈a0 && q∈a1}
The property X q || F p accepts words of the language
{ w = w0w1w2... | q ∈ w1 or ∃wi. p ∈ wi }
Another way to look at the accepted language is to draw the Buchi Automaton corresponding to the LTL formula X q || F p:
Credits: image generated with ltl2ba
Is it possible to have guards on lambda functions?
For example:
\k
| k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
Other answers show how the extensions LambdaCase and MultiWayIf, introduced since this answer was first written, can solve this. Without them, the nearest direct translation is something a bit like
\k -> case () of
_ | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
As of GHC 7.6.1 there is an extension called MultiWayIf that lets you write the following:
\k -> if
| k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
Which at the very least is more pleasant to look at than the alternative using case.
For pattern-matching, there is a related extension called LambdaCase:
\case
"negative" -> -1
"zero" -> 0
"positive" -> 1
_ -> error "invalid sign"
These extensions are not part of standard Haskell, though, and need to be enabled explicitly via a {-# LANGUAGE LambdaCase #-} or {-# LANGUAGE MultiWayIf #-} pragma at the top of the file, or by compiling with the flag -XLambdaCase or -XMultiWayIf.
I like to keep lambdas short and sweet so as not to break the reader's visual flow. For a function whose definition is syntactically bulky enough to warrant guards, why not stick it in a where clause?
showSign k = mysign ++ " (" ++ show k ++ ")"
where
mysign
| k < 0 = "negative"
| k == 0 = "zero"
| otherwise = "positive"
An elegant and concise way to do it with LambdaCase:
{-# LANGUAGE LambdaCase #-}
\case k | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
or
\case
k | k < 0 -> "negative"
| k == 0 -> "zero"
| otherwise -> "positive"
A case when I used it, to catch an EOF error:
{-# LANGUAGE ScopedTypeVariables #-}
o <- hGetContents e `catch` (\case (e :: IOException) | isEOFError e -> return "")
Yet another way uses a combination of the LambdaCase and ViewPatterns GHC extensions:
{-# LANGUAGE LambdaCase, ViewPatterns #-}
\case
((< 0) -> True) -> "negative"
((==0) -> True) -> "zero"
_ -> "positive"
This keeps you from having to name an intermediate variable.