Is there a way to pattern match any list without iterating through the two cases: empty or non-empty list ?
I would like to fix the following code:
foo [] = "something else"
foo [_:_] = "something else"
Since the part in something else is the same I would like to remove it from one place.
Thank you.
The pattern _ matches anything without binding it to a name. A name, like say, xs also matches anything. So you can do either:
foo _ = "something else"
or
foo xs = "something else"
If "something else" truly does not depend on the value of xs the first form is preferred, so that another programmer (and you) can quickly spot that the value is irrelevant in this particular equation.
Unfortunately, your first case is already of the second form, so it matches all possibilities. The other cases will never be reached.
Related
I have a list of Strings, errors. I do some checks and if any fail, I append a message to errors. Something like this:
let errors = []
let errors' = errors ++ if (check1 fails) then ["check1 failed"] else []
let errors'' = errors' ++ if (check2 fails) then ["check2 failed"] else []
Surely there is a more idiomatic way to accumulate changes to errors without making a new variable every time. Do I need to break out Data.IORef for mutable variables? Seems like overkill.
If I simply remove the apostrophes, the compiler returns an error because it gets caught in an infinite loop.
You could group the conditions and messages together
checksTodo = [(check1 fails, "check1 failed"), (check2 fails, "check2 failed")]
errors = map snd (filter fst checksTodo)
If you are comfortable using the list comprehension syntax, you could instead write it in a more readable fashion:
errors = [ msg | (cond, msg) <- checksTodo, cond ]
If I simply remove the apostrophes, the compiler returns an error because it gets caught in an infinite loop.
This is happening because let bindings in Haskell (unlike most languages) are recursive by default. Which means that if you say
let errors = errors ++ if (check1 fails) then ["check1 failed"] else []
the compiler will treat it as a recursive definition. When you try to evaluate errors at runtime, you go into an infinite loop as you need errors to compute errors.
Another alternative:
let errors =
[ "check1 failed" | check1 fails ] ++
[ "check2 failed" | check2 fails ] ++
...
What theindigamer said, plus, the idiomatic way to do error checking is usually having your checker return an Either: if something goes wrong, produce a Left with the error message, otherwise a Right with the result.
Since, in this case, your checks aren't producing an actual result, you can make the result the unit type (); thus, you can convert your checks to generate Either like this:
check1Either = if check1 fails then Left "check1 failed" else Right ()
And then, just run the checks and filter the elements with a Left using the lefts function in Data.Either:
import Data.Either
errors = lefts [check1Either, check2Either]
(You might ask, if there isn't going to be a result to fill Right with, why not use Maybe? You can, and filter errors with catMaybes from Data.Maybe; it's just that Nothing is usually interpreted to mean that the computation failed, and Just usually means success - the opposite of what happens here - whereas, idiomatically speaking Left is usually interpreted as an error)
Why is the function name repeated in
example:
lucky :: (Integral a) => a -> String
lucky 7 = "LUCKY NUMBER SEVEN!"
lucky x = "Sorry, you're out of luck, pal!"
when should I not be repeating function name? what is the meaning of it?
thanks
What you are seeing is pattern match in action.
I will show you another example:
test 1 = "one"
test 2 = "two"
test 3 = "three"
Demo in ghci:
ghci> test 1
"one"
ghci> test 2
"two"
ghci> test 3
"three"
ghci> test 4
"*** Exception: Non-exhaustive patterns in function test
So, when you call any function, the runtime system will try to match
the input with the defined function. So a call to test 3 will
initially check test 1 and since 1 is not equal to 3, it will
move on to the next definition. Again since 2 is not equal to 3,
it will move to the next defintion. In the next definiton since 3 is
equal to 3 it will return "three" String back. When you try to
pattern match something, which doesn't exist at all, the program
throws the exception.
This kind of pattern matching can be transformed to a case statement (and indeed, that's what compilers will normally do!):
lucky' n = case n of
7 -> "LUCKY NUMBER SEVEN!"
x -> "Sorry, you're out of luck, pal!"
Because the x isn't really used, you'd normally write _ -> "Sorry, ..." instead.
Note that this is not2 the same as
lucky'' n = if n==7 then ...
Equality comparison with (==) is in general more expensive1 than pattern matching, and also comes out uglier.
1 Why it's more expensive: suppose we have a big data structure. To determine that they are equal, the program will need to dig through both entire structures, make sure really all branches are equal. However, if you pattern match, you will just compare a small part you're interested in right now.
2 Actually, it is the same in the case, but just because the compiler has a particular trick for pattern matching on numbers: it rewrites it with (==). This is really special for Num types and not true for anything else. (Except if you use the OverloadedStrings extension.)
That definition of lucky uses "pattern matching", and equals (in this case)
lucky :: (Integral a) => a -> String
lucky a = if a == 7
then "LUCKY NUMBER SEVEN!"
else "Sorry, you're out of luck, pal!"
I assume you're looking at learn you a haskell. After that example, it says that
When you call lucky, the patterns will be checked from top to bottom and when it conforms to a pattern, the corresponding function body will be used.
So the first line indicates the type of the function, and later lines are patterns to check. Each line has the function name so the compiler knows you're still talking about the same function.
Think of it this way: When you write the expression lucky (a+b) or whatever, the compiler will attempt to replace lucky (a+b) with the first thing before the = in the function definition that "fits." So if a=3 and b=4, you get this series of replacements:
lucky (a+b) =
lucky (3+4) =
--pattern matching occurs...
lucky 7 =
"LUCKY NUMBER SEVEN!"
This is part of what makes Haskell so easy to reason about in practice; you get a system that works similarly to math.
I have a question regarding Haskell that's been stumping my brain. I'm currently required to write a function that removes a string i.e. "word" from a list of strings ["hi", "today", "word", "Word", "WORD"] returns the list ["hi", "today", "Word", "WORD"]. I cannot use any higher-order functions and can only resort to primitive recursion.
Thinking about the problem, I thought maybe I could solve it by using a recursion where you search the head of the first string, if it matches "w" then compare the next head from the tail, and see if that matches "o". But then I soon realized that after all that work, you wouldn't be able to delete the complete string "word".
My question really being how do I compare a whole string in a list rather than only comparing 1 element at a time with something like: removeWord (x:xs). Is it even possible? Do I have to write a helper function to aid in the solution?
Consider the base case: removing a word from an empty list will be the empty list. This can be trivially written like so:
removeWord [] _ = []
Now consider the case where the list is not empty. You match this with x:xs. You can use a guard to select between these two conditions:
x is the word you want to remove. (x == word)
x is not the word you want to remove. (otherwise)
You don't need a helper function, though you could write one if you wanted to. You've basically got 3 conditions:
You get an empty list.
You get a list whose first element is the one you want to remove.
You get a list whose first element is anything else.
In other languages, you would do this with a set of if-else statements, or with a case statement, or a cond. In Haskell, you can do this with guards:
remove_word_recursive:: String -> [String] -> [String]
remove_word_recursive _ [] = []
remove_word_recursive test_word (x:xs) | test_word == x = what in this case?
remove_word_recursive test_word (x:xs) = what in default case?
Fill in the correct result for this function in these two conditions, and you should be done.
I think what you're looking for is a special case of the function sought for this question on string filters: Haskell - filter string list based on some conditions . Reading some of the discussion on the accepted answer might help you understand more of Haskell.
Since you want to remove a list element, it's easy to do it with List Comprehension.
myList = ["hi", "today", "word", "Word", "WORD"]
[x | x <- myList, x /= "word"]
The result is:
["hi","today","Word","WORD"]
If isInfixOf is not considered as higher order, then
import Data.List (isInfixOf)
filter (not . isInfixOf "word") ["hi", "today", "word", "Word", "WORD"]
I want to add non null items to a List. So I do this:
List<Foo> foos = []
Foo foo = makeFoo()
if (foo)
foos << foo
But is there a way to do it in a single operation (without using findAll after the creation of the list). Like:
foos.addNonNull(makeFoo())
Another alternative is to use a short circuit expression:
foo && foos << foo
The foo variable must evaluate to true for the second part to be evaluated. This is a common practice in some other languages but I'd hesitate to use it widely in groovy due to readability issues and conventions.
No, you'd need to use an if, or write your own addNonNull method (which just uses an if)
Also:
if( foo ) {
probably isn't enough, as this will skip empty strings, or 0 if it returns integers
You'd need
if( foo != null ) {
The answer is YES! we can get rid of assigning a variable
Foo foo = makeFoo()//we can ditch this
The answer is NO we can't get rid of the condition. BUT we can make it more compact.
Here's how
List<Foo> foos = []
foos += (makeFoo()?:[]);
The trick is groovy's "+" operator which works differently based on what is to the left and what is to the right of the "+". It just so happens that if what is on the left is a list and what is on the right is an empty list, nothing gets added to the list on the left.
Pros are it is quick to type and compact.
Cons are it is not instantly obvious what is happening to most people
AND we replaced the variable assignment with an extra operation. Groovy is
going to try to do something to List foos no matter what, it just so happens that in the second case the result of that operation gives us a desired result.
I'm new to Haskell and I'm trying out a few tutorials.
I wrote this script:
lucky::(Integral a)=> a-> String
lucky 7 = "LUCKY NUMBER 7"
lucky x = "Bad luck"
I saved this as lucky.hs and ran it in the interpreter and it works fine.
But I am unsure about function definitions. It seems from the little I have read that I could equally define the function lucky as follows (function name is lucky2):
lucky2::(Integral a)=> a-> String
lucky2 x=(if x== 7 then "LUCKY NUMBER 7" else "Bad luck")
Both seem to work equally well. Clearly function lucky is clearer to read but is the lucky2 a correct way to write a function?
They are both correct. Arguably, the first one is more idiomatic Haskell because it uses its very important feature called pattern matching. In this form, it would usually be written as:
lucky::(Integral a)=> a-> String
lucky 7 = "LUCKY NUMBER 7"
lucky _ = "Bad luck"
The underscore signifies the fact that you are ignoring the exact form (value) of your parameter. You only care that it is different than 7, which was the pattern captured by your previous declaration.
The importance of pattern matching is best illustrated by function that operates on more complicated data, such as lists. If you were to write a function that computes a length of list, for example, you would likely start by providing a variant for empty lists:
len [] = 0
The [] clause is a pattern, which is set to match empty lists. Empty lists obviously have length of 0, so that's what we are having our function return.
The other part of len would be the following:
len (x:xs) = 1 + len xs
Here, you are matching on the pattern (x:xs). Colon : is the so-called cons operator: it is appending a value to list. An expression x:xs is therefore a pattern which matches some element (x) being appended to some list (xs). As a whole, it matches a list which has at least one element, since xs can also be an empty list ([]).
This second definition of len is also pretty straightforward. You compute the length of remaining list (len xs) and at 1 to it, which corresponds to the first element (x).
(The usual way to write the above definition would be:
len (_:xs) = 1 + len xs
which again signifies that you do not care what the first element is, only that it exists).
A 3rd way to write this would be using guards:
lucky n
| n == 7 = "lucky"
| otherwise = "unlucky"
There is no reason to be confused about that. There is always more than 1 way to do it. Note that this would be true even if there were no pattern matching or guards and you had to use the if.
All of the forms we've covered so far use so-called syntactic sugar provided by Haskell. Pattern guards are transformed to ordinary case expressions, as well as multiple function clauses and if expressions. Hence the most low-level, unsugared way to write this would be perhaps:
lucky n = case n of
7 -> "lucky"
_ -> "unlucky"
While it is good that you check for idiomatic ways I'd recommend to a beginner that he uses whatever works for him best, whatever he understands best. For example, if one does (not yet) understand points free style, there is no reason to force it. It will come to you sooner or later.