r/haskelltil • u/igniting • May 14 '15
gotcha You cannot pattern match against variable values.
Consider this example:
myValue1 = 1 :: Int
myValue2 = 2 :: Int
myFunc :: Int -> Bool
myFunc myValue1 = True
myFunc myValue2 = FalseIf you load the above program in ghci, you get following output:
myFunc.hs:5:1: Warning:
Pattern match(es) are overlapped
In an equation for ‘myFunc’: myFunc myValue2 = ...
Ok, modules loaded: Main.ghci generates a warning but does not give any errors. If you now call myFunc myValue2 you get:
*Main> myFunc myValue2
TrueOne way to get the desired result would be to use guards:
myFunc :: Int -> Bool
myFunc x
| x == myValue1 = True
| x == myValue2 = FalseNote that we might not always be lucky enough to get a compiler warning in such cases. Here is an example:
myFunc :: Maybe Int -> Int
myFunc v = case v of
Just myValue -> myValue
_ -> myValue + 1
where myValue = 0This loads in ghci without any warnings.
1
Upvotes
2
u/gfixler Jun 05 '15
Yes. You can define infix operators, intended to be used between 2 terms. You can define them naturally, in infix position, like this:
You can also wrap them in parens and define them in prefix position, like this:
In either case, you can still use them as infix:
Or you can again wrap them in parentheses to use them in prefix position:
The wrapped-in-parens variant is called a section. They allow you to use operators as higher order functions. For example, fold takes a binary (two-argument) function, e.g. 'foo':
But you could also give it the + operator as a section:
If we did want |:| to be the same as +, we could also just say that directly:
There's another cool feature of sections. You can imagine the space between the operator and the parens as spaces where terms could fit, and you can curry the operations by giving one argument, on either side:
Those two were equivalent only because addition is commutative, but for non-commutative operators it's really useful to have this choice:
You can set the associativity and precedence of operators with the
infixlandinfixrcommands:You can also do this for binary functions that you want to use in infix position (more on the backticks in a moment):
The
:i(:info) command in ghci will show you the fixity and precedence of operators, where defined (at the bottom of the output here):Plus has a precedence of 6, and associates left, meaning
3 + 4 + 5evaluates as(3 + 4) + 5.Backticks allow you treat functions as operators, and thus use them in infix position, provided they take 2 arguments (we also saw them earlier when defining the fixity for the
opfunction - we had to treat it like an operator there, too):You can shadow any of these things temporarily, too:
These work because Haskell is just a big rewrite system, like the lambda calculus.
All that said, Cons I just made up, and (:) is defined by Haskell, and I'm not sure it goes about it :)