Can you have multiple evaluations in your WHEN clause?
For example is there a way to do something like this:
when (x == "Open" and y == "Ready") $ do...
I can get a single condition to work, but what if I need both to be true?
How about something like
when (x == "Open" && y == "Ready") $ do
...
&& is just a normal infix operator defined as
True && a = a
False && _ = False
Notice that with laziness this has exactly the same short circuiting properties we get in other languages!
On a totally separate note, instead of using strings to represent different states the Haskell-ish way would be to define your own type
data StateOfFoo = Ready
| Open
| Closed
| ...
deriving(Eq)
and then use x == Open && y == Ready for example. This way you make it clear in the types what you expect x and y to be.
Related
I was wondering if there is a simpler or shorter way to write repetitive conditions like x == 1 && y == 1 && z == 1?
When it is (exactly) repeated code, you should consider to extract the statement into a method and give a meaningfull name, which you know from the context where it is used. This makes the requirement (reading the code) easier to understand, at the point where it is used. And it makes it also easier to spot the it is always the same condition.
if (conditionName(x, y, z)) {
}
fun boolean conditionName(int x, int y, int z) {
return x == 1 && y == 1 && z == 1;
}
I cannot think of a shorter statement for the condition, but a method extraction will improve your code readability, which should be your overall goal.
You could consider using predicates using all. For example:
listOf(x, y, z).all {it == 1}
This will return true when x==1, y==1, and z==1.
If the goal is to shorten what you want, there's not much legroom as your boolean expression is already very concise. Some of the other answers have illustrated how to make what you want more readable, however.
You can make a convenience function for this kind of repeated code (or if you just need it to be more readable, or safer to edit):
fun <T> T.allEqual(vararg items: T) = items.all { it == this }
// or you could make the receiver the first parameter instead, this is just
// more explicit about which item is the value being compared against
1.allEqual(x, y, z)
But no, there isn't any other shorthand built into the language as far as I'm aware - conditions like x == 1 chained with boolean operators are about as simple as it can get! If you want to check multiple things without repeating yourself, any and all make that easy, while being flexible for all kinds of situations, and allowing the user to put together the functionality they need with those more general functions.
If you specifically want a version of all that does a simple comparison to a single value, and doesn't require creating an iterable like listOf, you have to write your own with those tools (which is basically what I've done). It's up to you if you think it's worth it!
If it makes sense you could hold those variables in a class
data class XYZ(
val x: Int,
val y: Int,
val z: Int)
And compare your instance with XYZ(1, 1, 1);
Or if it's just those three variables, you could write
if (Triple(x, y, z) == Triple(1, 1, 1))
val x = 1
val y = 1
var z = 1
println("$x$y$z" == "111") // prints 'true'
z = 2
println("$x$y$z" == "111") // prints 'false'
Many books and tutorials explain language features with small scripts that do asserts. If all the assertions pass, the process has an exit code of 0, and if any one fails, the process has a non-zero exit code. For example, in Python:
assert type(int) == type
assert len(list(x for x in range(3))) == 3
assert {'x': 1}['x'] == 1
and in Lua:
assert(type(7.299E-3) == "number")
assert(#{10, 20, 30} == 3)
assert(utf8.len("cafés") == 5)
In Ruby we can fake it in a nice way:
fail unless 5.send(:abs) == 5
fail unless 5.send('abs') == 5
fail unless 5.abs == 5
But I'm having trouble finding the equivalent in Haskell. When I tried to use error directly, in this script:
main = do
{ 1 == 1 || error "nope"
; 3 == 3 || error "nope"
; 8 == 8 || error "nope"
}
I get the error
error:
• Couldn't match expected type ‘m a0’ with actual type ‘Bool’
• In a stmt of a 'do' block: 1 == 1 || error "nope"
which makes sense given the expected type of main. Now I was able to do what I wanted by writing my own module on the side:
module SimpleAssert (assertAll) where
import Data.List (all)
assertAll assertions =
if all ((==) True) assertions
then return "ok"
else error "Assertion failure"
Then my script is the relatively clean:
import SimpleAssert (assertAll)
main = do
assertAll
[ 1 == 1
, 3 == 3
, 8 == 8
]
However it not as stand-alone as in the other languages (nor does it give me any indication of where the actual assertion failed, but I can live with that). Is there a way in Haskell to do without the external assert function? I do know about unit tests in Haskell, but that too has some "overhead." Perhaps the overhead is fine and proper, and maybe an external function is the right way to go, but I'm interested to know if Haskell supports some kind of lightweight approach to this. Does such a (lightweight) way exist?
Not fully sure if this meets your needs, but one simple option is to use unless:
main = do
unless (1 == 1) (error "nope")
unless (3 == 3) (error "nope")
unless (8 == 8) (error "nope")
and you could of course easily factor out a separate "assert" function from this if you want to.
I have many functions (no arguments ) like below and all return a Bool
t0 = 2 == (1+1)
t1 = "" == []
And all the way up to t99
Can I create a list with all these function results. An example is below but I have to type it all out...
tests = [t0,t1,t2,t3,t4,t5 ........... t99]
Can I do something with list comprehension to avoid typing that all out ??
Thanks
If instead of t0 through t99, you write
t 0 = 2 == 1+1
t 1 = "" == []
-- ...
t 99 = 'a' == pred 'b'
then you can use map t [0..99] to apply t to the numbers 0 through 99.
in designing an algebraic equation modelling system, I had this dilemma: we cannot associate properties to a number, if I turn the number to a table with a field "value" for example, I can overload arithmetic operators, but not the logic operator since that only works when both operands have same metatable, while my users will compare "x" with numbers frequently.
For example, here is a minimal equation solver system:
x = 0
y = 0
eq1 = {function() return 2*x + 3*y end, rhs = 1 }
eq2 = {function() return 3*x + 2*y end, rhs = 2 }
p = {{x,y},{eq1, eq2}}
solve(p)
The "solve()" will process table "p" to get all coefficients of the equation system and rhs. However, it is essential, a user can associate properties to "x" and "y", for example, lower bound, upper bound. I tries using table,
x = {val=0, lb=0, ub=3}
y = {val=1,lb=3,ub=5}
....
and write metamethods for "x" and "y" such that arithmetic operating will act on x.val and y.val. However, in a scripting environment, we also need to compare "x" with numbers, i.e., "if x>0 then ...". And I stuck here. An ugly solution is to ask users to use x.val, y.val everywhere in modelling the equation and scripting. Does anyone here has similar need to associate properties to a number, and the number can still be used in arithmetic/logic operations?
Something like this could work:
x = {val = 10}
mt = {}
mt.__lt = function (op1, op2)
if (type(op1) == 'table') then a = op1.val else a = op1 end
if (type(op2) == 'table') then b = op2.val else b = op2 end
return a < b
end
setmetatable(x, mt)
print(x < 5) -- prints false
print(x < 15) -- prints true
print(x < x) -- prints false
print(5 < x) -- prints true
Of course, you would write similar methods for the other operators (__add, __mul, __eq and so on).
If you'd rather not use type()/reflection, you can use an even dirtier trick that takes advantage of the fact that unary minus is well, unary:
mt = {}
mt.__unm = function (num) return -(num.val) end
mt.__lt = function (a, b) return -(-a) < -(-b) end
This is rather simple if you have access to the debug library, do you?
debug.setmetatable(0, meta)
meta will be the metatable of ALL numbers. This will solve your logical overloading problem.
However if you would prefer assigning properties to numbers, there is a way you could do this, I wrote a quick example on how one would do so:
local number_props = {
{val="hi"},
{val="hi2"}
}
debug.setmetatable(0,{__index=function(self,k)return number_props[self][k]end})
print((1).val, (2).val)
I am currently working on a function in Haskell that needs to do the following:
Declare the type and define a function that takes 3 numbers as input and checks if they are all different. Please give 3 versions of it. First use if else mechanism, then use guards, and third one use default of Haskell
I have completed it with if-else, and guards, but I don't know what "Default of Haskell" means? I'm not looking for anyone to do my work for me, but if someone could just clear up what I need to do, that would be great.
Thank you very much.
I think default means using just comparison operators.
different1 a b c = if a == b then False else if a == c then False else if b == c then False else True
different2 a b c| a == b = False
| b == c = False
| a == c = False
| otherwise = True
different3 a b c = a /= b && b /= c && a /= c