Error in Haskell code containing tuples - haskell

I have been trying to create a function in Haskell that will take a non-negative value which corresponds to minutes and return it in the format (days,hours,minutes) e.g. 4000 minutes will give (2, 18, 39).
My code keeps returning the error "file:.\prac0.hs:27 - Syntax error in input (unexpected `|')" on load.
Here is my code:
dayshoursmins :: Int->(Int,Int,Int)
dayshoursmins n = (x,y,z)
| n==0 = 0
| n`div`1440 =>1 = x && dayshoursmins(n`mod`1440)
| n`div`60 < 24 = y && dayshoursmins(n`mod`60)
| n < 60 = z

The pipe (|) is used as a guard, what you need is a where clause I think:
dayshoursmins :: Int->(Int,Int,Int)
dayshoursmins n = (d,h,m)
where d = div n 1440
dm = mod n 1440
h = div dm 60
m = mod dm 60
Running this with ghci gives:
*Main> dayshoursmins 2016
(1,9,36)
I don't really understand your code: it does seem to mix all kinds of concepts. After the = operator, you cannot put guards anymore.

Related

How to fix indentation problem with haskell if statement

I have the following Haskell code:
f :: Int -> Int
f x =
let var1 = there in
case (there) of
12 -> 0
otherwise | (there - 1) >= 4 -> 2
| (there + 1) <= 2 -> 3
where there = 6
The function alone is garbage, ignore what exactly it does.
I want to replace the guards with if
f x =
let var1 = there in
case (there) of
12 -> 0
otherwise -> if (there - 1) >= 4 then 2
else if (there + 1) <= 2 then 3
where there = 6
I tried moving the if to the next line, the then to the next line, lining them up, unlining them, but nothing seems to work.
I get a parsing error and I don't know how to fix it:
parse error (possibly incorrect indentation or mismatched brackets)
|
40 | where there = 6
| ^
You have a few misunderstandings in here. Let's step through them starting from your original code:
f x =
A function definition, but the function never uses the parameter x. Strictly speaking this is a warning and not an error, but most code bases will use -Werror so consider omitting the parameter or using _ to indicate you are explicitly ignoring the variable.
let var1 = there in
This is unnecessary - again you are not using var1 (the below used there) so why have it?
case (there) of
Sure. Or just case there of, not need for excessive parens cluttering up the code.
12 -> 0
Here 12 is a pattern match, and it's fine.
otherwise ->
Here you used the variable name otherwise as a pattern which will uncondtionally match the value there. This is another warning: otherwise is a global value equal to True so it can be used in guards, such as function foo | foo < 1 = expr1 ; | otherwise = expr2. Your use is not like that, using otherwise as a pattern shadows the global value. Instead consider the catch all pattern with underscore:
_ -> if (there - 1) >= 4
then 2
else if (there + 1) <= 2
then 3
where there = 6
Ok... what if there was equal to 3? 3-1 is not greater than 4. 3+1 is not less than 2. You always need an else with your if statement. There is no if {} in Haskell instead there is if ... else ... much like the ternary operator in C, as explained in the Haskell wiki.

Why is a part of my where clause not used in my conditional function?

I've been practicing Haskell as part of my course at my university, and I made the following function while experimenting with local definitions :
fac1 x | x == 0 = zero
| x == 1 = one
| otherwise = x * fac1 (x-1)
where zero = 0
one = 1
I would expect any call to fac1 result in zero because when x==0, it will multiply by 0. However, it gives me the correct number.
Conversely, writing one = 0 instead of one = 1 results in my results being 0. I would expect the same sort of behavior for zero, but changing the value of it does nothing. I feel like it should be happening since I clearly included a x==0 condition. The x==1 is evaluated, why not x==0?
Can someone explain what error I made?
Your recursion stops on x = 1, not x = 0.
Let's evaluate fac1 2 by hand:
fac1 2
= 2 * fac1 (2 - 1) -- 2 is neither 0 nor 1, so we take the "otherwise" case
= 2 * fac1 1 -- evaluate 2 - 1
= 2 * one -- x == 1 holds, so we return "one"
= 2 * 1 -- one is 1
= 2 -- done

Error specified for negative numbers displayed when function applied to a Fractional. Why?

I am trying to learn Haskell, and I defined the following simple recursive function to calculate the factorial.
fact n | n < 0 = error "fact only valid for non-negative integers"
| n == 0 = 1
| n > 0 = n * fact(n-1)
It works fine for a positive integer, and as expected when invoked with a negative integer, it throws the error that I have specified.
What is the problem?: It gives me the same error ("fact only valid for non-negative integers") when I try to apply it to a Fractional, such as fact 10.5. Why does it give me that same error that I have clearly specified should apply for only the case of n < 0.
If you give it 10.5 as argument, then the third case is valid, and the function calls itself recursively with n = 10.5 - 1 = 9.5.
That input also triggers the third case, making a recursive call with n = 8.5.
And so on: 7.5, then 6.5, then 5.5, 4.5, 3.5, 2.5, 1.5, 0.5
And then, on the next iteration, n = -0.5, which triggers the first case and produces the error. Everything exactly as coded.
If you want your function to work for fractional numbers, you have to (a) define what is a factorial of n for 0 < n < 1, and then (b) encode that case.
For example, if I were to define factorial of a number between zero and one to be equal to one, then the function would look like this:
fact n | n < 0 = error "fact only valid for non-negative integers"
| n >= 0 && n <= 1 = 1
| n > 0 = n * fact(n-1)
Also, a side note: I think the above code should give you a warning that the function is partial. This is because the compiler cannot prove that one of the cases should always hold (and in all fairness, depending on the argument type and the definition of Num and Ord for it, it might not hold). To avoid this, one should use an otherwise clause:
fact n | n < 0 = error "fact only valid for non-negative integers"
| n >= 0 && n <= 1 = 1
| otherwise = n * fact(n-1)

Blockly code for translate numbers roman

I need to do a progam in blockly code for translate numbers from arabigos to roman up to 4000,but I don't know what I am doing wrong .
I only can use functions ,variables ,maths and logic (attached html code ).
who can help me with this please ,I'll be thankful ;))
https://blockly-demo.appspot.com/static/demos/code/index.html#zq536j
Let me see if I can think of something :)
Perhaps an example can help me: n = 1234 I can start by dividing by 1000 and take the integer part:
M = Math.floor(n/1000)
now M is 1 Now I can remove 1000*M from n and continue:
n = n-1000*M -> so now n is only 234.
After that:
D = Math.floor(n/500)
n = n-500*D
so D is 0 and n is still 234, because 234 does not contain any 500-eds.
And so no:
C = Math.floor(n/100)
n = n-100*C
which gives that C is 2 and n is 34.
And so on:
L = Math.floor(n/50)
n = n-50*L
which gives that L is 0 and n is 34.
Then:
X = Math.floor(n/10)
n = n-10*X
which gives that X is 3 and n is 4.
And finally
I = n
So now:
M=1
D=0
C=2
L=0
X=3
I=4
so you just have to make a clever enough function that prints it like:
"M CC XXX IV"
and you are done ;)
PS I hope this was not homework :D

Using a combination of IF, And in excel VBA

Im trying make a condition in excel VBA where there are two posible condition of variable x and y,
Say for example
Sub Test()
X = 6
Y = 11
If X < 3 Or X > 5 And Y < 10 Then
X = 10
Else
X = 11
End If
MsgBox X
End Sub
For the X term, when X<3 or X>5 seems work well however when i change the Y to any value greater than 10 say 11 then the result is 10 but supposed to be it should be 11. Can you please let me know if i missing something in my code so that when X<3 or X>5 and (y=11)>10 the result must be 11.
Regards,
Kenneth
This is an issue of operator precedence. In VB the order in Logical and Bitwise Operators is as follows:
Negation (Not)
Conjunction (And, AndAlso)
Inclusive disjunction (Or, OrElse)
Exclusive disjunction (Xor)
The result is that and is executed before or in your condition, leading to the right side of the or being the whole expression X > 5 And Y < 10.
Your condition is executed like:
If X < 3 Or (X > 5 And Y < 10) Then
I believe what you actually want is the following (this should solve your issue):
If (X < 3 Or X > 5) And Y < 10 Then
Sources:
MSDN: Operator Precedence in Visual Basic
Consider:
Sub Test()
X = 6
Y = 11
If (X < 3 Or X > 5) And Y < 10 Then
X = 10
Else
X = 11
End If
MsgBox X
End Sub

Resources