using a maybe and just for more then 3 variables - haskell

Hi I can't figure this out myself and i also couldn't find an example online
I'm trying to use a maybe or a guard and the examples i found have just two variables,
when i edit or follow the examples with more then two i get an error heres what i am trying to do
--maybe example
Fun :: Double -> Double -> Double -> Maybe Double
Fun a b c
| a >= -1.0 || a <= 1.0 || b >= -1.0 || b <=1.0 || c /=0 || c >= -1.0 = Nothing
| otherwise = Just max( ((c^ (-c)) + (a^(-c)-1.0) ^ (a+ (-1.0/a))) 0.0)
error with gchi
The function `Just' is applied to two arguments,
but its type `a0 -> Maybe a0' has only one
while hlint gives
No suggestions
trying to use a guard instead i get a different error
--guard example
Fun :: Double -> Double -> Double -> Maybe Double
Fun a b c
| a >= -1.0 || a <= 1.0 || b >= -1.0 || b <=1.0 || c /=0 || c >= -1.0 = error "Value out of range "
| otherwise = max( ((c^ (-c)) + (a^(-c)-1.0) ^ (a+ (-1.0/a))) 0.0)
and heres ghc and hlints errors
test.hs:10:1:
Invalid type signature: Fun :: Double
-> Double -> Double -> Maybe Double
Should be of form <variable> :: <type>
$ hlint test.hs
Error message:
Left-hand side of type signature is not a variable: Fun
Code:
Fun :: Double -> Double -> Double -> Maybe Double
> Fun a b c

You must write functions with a lower-case letter. This means writing this:
fun :: Double -> Double -> Double -> Maybe Double
fun a b c ...
Functions can never start with upper-case letters, since upper-case identifiers are reserved for modules (Data.List for example) and type constructors and data constructors (like Int or Maybe or Just) and some other things.
You also have an issue with the application of the Just constructor. If you write this:
Just max(something)
... it means the same thing as:
Just max something
i.e. you are giving Just two arguments. You need to fix this by adjusting your parens:
Just (max something)

Syntax errors, mostly:
f :: Double -> Double -> Double -> Maybe Double
f a b c
| a >= -1
|| a <= 1
|| b >= -1
|| b <= 1
|| c /= 0
|| c >= -1
= Nothing
| otherwise
= Just $ max ((c ** (-c)) + (a ** (-c)-1) ** (a+ (-1/a))) 0
Note the use of the more generally-typed exponention operator, (**), and $ to avoid parens in the Just wrapper over max.

Related

Can you use `fromIntegral` to solve this type error?

Would using fromIntegral help fix this type error I'm getting.
Couldn't match expected type ‘Float’ with actual type ‘Int’?
If not, how can I resolve it?
taxiFare :: Int -> Float
taxiFare x | x >= 10 = longRide
| otherwise = shortRide
where
longRide = 2.2 + (x * 0.3) + 2
shortRide = 2.2 + (x * 0.5)
The problem is that your signature specifies that x is an Int. But the result type should be a Float since calculations like (*) :: Num a => a -> a -> a and (+) :: Num a => a -> a -> a require the two operands and the result to be all of the same type, it thus means that x should be a Float.
You can make use of fromIntegral :: (Integral a, Num b) => a -> b to convert any Integral type to any Num type, so yes. You can define for example a variable that will store the Float counterpart of x and use that variable:
taxiFare :: Int -> Float
taxiFare x
| x >= 10 = longRide
| otherwise = shortRide
where longRide = 0.3 * xf + 4.2
shortRide = 0.5 * xf + 2.2
xf = fromIntegral x

Haskell program for calculating 3rd roots

The error now iCouldn't match expected type ‘Double’
with actual type ‘Double -> Double -> Double -> Double’ , Probable cause: ‘(+)’ is applied to too few arguments
In the expression: cubicQ ^ 3 + r ^^ 2
In an equation for ‘cubicDisc’: cubicDisc q r = cubicQ ^ 3 + r ^^ 2
cubicR :: Double -> Double -> Double -> Double -> Double
cubicR a b c d = (9*a*b*c-27*a^^2*d-2*b^^3)/(54*a^^3)
cubicQ :: Double -> Double -> Double -> Double
cubicQ a b c = (3*a*c-b^^2)/(9*a^^2)
cubicDisc :: Double -> Double -> Double
cubicDisc q r = cubicQ^3 + r^^2
cubicS :: Double -> Double -> Double
cubicS q r = (r + sqrt(q^^3+r^^2))**(1/3)
cubicT :: Double -> Double -> Double
cubicT q r = (r - sqrt(q^^3+r^^2))**(1/3)
cubicRealSolutions :: Double -> Double -> Double -> Double -> [Double]
cubicRealSolutions a b c d = if cubicDisc > 0 || root == 0
then [rootOne,rootTwo,rootThree]
else []
where
rootOne= (cubicS + cubicT) - b/(3*a)
rootTwo = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
rootThree = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
Syntactically, your program does not make sense, that's what the compiler is complaining about. First, the if statement is just floating around; its not in the same scope as cubicRealSolutions. I would recommend revising and reading through some Haskell documentation on let, if, and function syntax . For now, if I were you I would clean up the code as follows:
cubicRealSolutions :: Double -> Double -> Double -> Double -> [Double]
cubicRealSolutions a b c d = if cubicDisc > 0 || root == 0
then [rootOne,rootTwo,rootThree]
else []
where
root = 0
rootOne= (cubicS + cubicT) - b/(3*a)
rootTwo = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
rootThree = (cubicS+cubicT)/2 -(b)/(3*a) + sqrt(3)/2*(cubicS-cubicT)
cubicDisc = 18*a*b*c*d - 4*(b^3)*d + (b^2)*(c^2) - 4*a*c^3 - 27*(a^2)*(d^2)
cubicS = 0.1
cubicT = 0.2
However, there are still major issues with this code and it will not compile because root,cubicDisc, cubicS, cubicT are not defined. Also, you never use the parameters c or d which I find odd, as you probably want to use them. Finally, if statements must evaluate to the same type, hence the else evaluates to an empty list instead of a string. Even my revision is not "good" style. There are too many statements in the where clause. If this happens its best to break the function down into smaller parts to avoid run-on where clauses. I've used ... to indicate what you need to define for the compiler.
References: LYAH
PS: Personally, I find where syntax to be easier to understand than let but that is up to personal style choices. Although, let is a bit more flexible than where.
EDIT: I have defined root, cubicS, and cubicT with placeholder values to illustrate that they must evaluate to a Double.

Why am i getting this error (arising from a use of ‘print’) [duplicate]

I have the following code which uses Newton's method to approximate the square root of some number. The problems is that when I run it, I get an error..What is wrong and how can I fix it?
newtonRootSequence :: Double -> [Double]
newtonRootSequence d = newtonSequenceGenerator d 1
newtonSequenceGenerator :: Double -> Double -> [Double]
newtonSequenceGenerator d xn = nxplus1 : newtonSequenceGenerator d nxplus1
where nxplus1 = (xn + d / xn) / 2
newtonRoot:: Double -> Double -> Double
newtonRoot d epsilon = head ([xs !! index | index <- [1..((length xs) - 1)], (xs !! index) - (xs !! index - 1) <= epsilon]
where xs = newtonRootSequence d
Error:
<interactive>:2:1: error:
* No instance for (Show (Double -> Double))
arising from a use of `print'
(maybe you haven't applied a function to enough arguments?)
* In a stmt of an interactive GHCi command: print it
Running it should be like the following:
$newtonRoot 35
In Haskell all function are curryfied, so, your function
newtonRoot:: Double -> Double -> Double
the are "hidden parenthesis":
newtonRoot:: Double -> (Double -> Double)
if you provide one argument newtonRoot 35 you have
(newtonRoot 35) :: Double -> Double
and a function f :: Double -> Double is not instance of Show type class
You need to finally provide the last argument to your function value:
(newtonRoot 35 2) :: Double
Double can me shown
newtonRoot takes two arguments, a d and an epsilon. You didn't supply an epsilon. Try
> newtonRoot 35 0.1
instead.
There are other errors, too, but this should get you started down the debugging path.

Could not deduce (Num [Char]) arising from the literal

guys, i just started learning haskell (and to code) and i have ran into a problem that i can't figure out. So there is this exercise in which i have to present the number of solutions for a 2nd degree equation.
valid a b c = if [a,b,c] == [0,0,0] then False
else (if [a,b] == [0,0] then False
else (if a == 0 then False
else True)) --function to make sure it is a 2nd degree eq
nRaizes a b c = if valid a b c == False then "not a valid eq"
else (if (b^2 - 4 * a * c) > 0 then 2
else (if ((b^2 - 4 * a * c) == 0) then 1
else 0))
Everything looked fine to me, but when i try to load the script in GHCI i get the error message:
Could not deduce (Num [Char]) arising from the literal ‘2’
from the context (Num a, Ord a)
bound by the inferred type of
nRaizes :: (Num a, Ord a) => a -> a -> a -> [Char]
at ficha1.hs:(18,1)-(21,13)
In the expression: 2
In the expression:
(if (b * b - 4 * a * c) > 0 then
2
else
(if ((b * b - 4 * a * c) == 0) then 1 else 0))
In the expression:
if valid a b c == False then
"not a valid eq"
else
(if (b * b - 4 * a * c) > 0 then
2
else
(if ((b * b - 4 * a * c) == 0) then 1 else 0))
Failed, modules loaded: none.
Can someone explain to me what is wrong with this code? And how can i fix it? Thanks
As I already commented, you should always have a type signature, before even writing any actual code. First make it clear what the purpose of your code is, before actually implementing anything!
So, valid takes three numbers and checks them in some way, yielding False or True – i.e., a boolean. Hence, a valid signature would be
valid :: Int -> Int -> Int -> Bool
This would limit the arguments to machine-sized integers – fast but not overflow-safe. It could also be
valid :: Integer -> Integer -> Integer -> Bool
or, for floating-point real numbers,
valid :: Double -> Double -> Double -> Bool
In fact, you don't need to settle on a particular type: it can be any number type, it just needs to support equality comparison. The “correct” signature would be
valid :: (Num a, Eq a) => a -> a -> a -> Bool
That's indeed also what GHC infers if you just give it the code without a type signature:
Prelude> :t valid
valid :: (Eq a, Num a) => a -> a -> a -> Bool
But the compiler can only get this right by itself because the function valid happens to be type-correct. If you put in some mistake, then the compiler has no idea what the type should be, and hence likely infer some nonsensical type that leads to a cryptic error message. (This is only one of the reasons why you should write the signature first.)
That's what happened in nraized. This also takes three numbers and gives one number. Let's keep it simple:
valid :: Double -> Double -> Double -> Int
That should certainly be ok (though you can certainly make it more generic).
Now the error message is much clearer:
<interactive>:16:87:
Couldn't match expected type ‘Int’ with actual type ‘[Char]’
In the expression: "not a valid eq"
In the expression:
if valid a b c == False then
"not a valid eq"
else
(if (b ^ 2 - 4 * a * c) > 0 then
2
else
(if ((b ^ 2 - 4 * a * c) == 0) then 1 else 0))
What this tells you is that "not a valid eq" is incompatible with the type Int. Pretty obvious actually, isn't it? A function that's supposed to return 0, 1 or 2 shouldn't be able to return a string!
If you really want this to be an error case, you should mark it as such:
nRaizes a b c = if valid a b c == False then error "not a valid eq"
...
Here, the string is not a result: if that case is encountered, the program will simply be aborted and the error message prompted at the user, instead of trying to pass it on to further functions (which couldn't possibly give meaningful results anymore, just yet stranger errors).
A couple of stylistic notes
Generally avoid nesting if with explicit mention of True and False – this is needlessly complicated: comparisons yield booleans anyway. valid just gives false if any of the equalities hold; this could be written
valid a b c = if [a,b,c] == [0,0,0]
|| [a,b] == [0,0]
|| a == 0
then False
else True
...but that's just the same as
valid a b c = not ([a,b,c] == [0,0,0] || [a,b] == [0,0] || a == 0)
or indeed
valid a b c = [a,b,c] /= [0,0,0] && [a,b] /= [0,0] && a /= 0
Anyway, these checks are heavily redundant. If a is not 0 then the list equalities can't possibly hold either! So,
valid a b c = a /= 0
would work just as well. Actually you're not even using the b and c argument, so just write
valid a _ _ = a /= 0
...or just don't define valid by itself at all: simply inline the condition a /= 0.
nRaizes a b c = if (a /= 0) == False then error "not a valid eq"
...
which is of course again completely roundabout: simply use
nRaizes a b c = if a == 0 then error "not a valid eq"
...
That still leaves you with some ugly nested ifs in nasty nested parens. Haskellers don't like that, the preferred style is to use guards:
nRaizes a b c
| a == 0 = error "not a valid eq"
| b^2 - 4*a*c > 0 = 2
| b^2 - 4*a*c == 0 = 1
| otherwise = 0
Still not optimal: you're computing the discriminant twice. Why not:
nRaizes a b c
| a == 0 = error "not a valid eq"
| d > 0 = 2
| d == 0 = 1
| otherwise = 0
where d = b^2 - 4*a*c
While error can be used like that, I wonder why you check this anyway at that point. If a==0 then it's not really a second-order polynomial, but so what? It still has a number of solutions. Really the error case should probably if all the coefficients are zero (because the number of solutions would be infinite). Hence I think the code you really want is probably the following:
nRaizes :: (Eq a, Floating a) => a -> a -> a -> Int
nRaizes a b c
| all (==0) [a,b,c] = error "Equation has infinite solutions"
| d > 0 = 2
| d == 0 = 1
| otherwise = 0
where d = b^2 - 4*a*c

How do I return the middle number in Haskell

I have the following beginning of a function, and am unsure as to how I should return Middle Number (i.e. the number that is neither the largest nor smallest):
middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
| ...
I would recommend you break the function into two steps: First, sort the three numbers. Then, take the middle element. For the first step, also consider if you can take it one step at a time; each step bringing it a bit closer to being fully sorted, then tail-recursing back to bring it even closer.
The "middle number" is larger than one of the numbers, but smaller than the other number. And there is only one middle number. The most mechanical way to solve this would be to start off
middleNumber a b c
| a < b && a > c = a
Check if a is the middle number by being less than b but greater than c.
Now what if a is the middle number, but it's actually greater than b and less than c? There's another guard. What if b is the middle number? There's another 2 guards. What if c is the middle number? There's 2 more guards, for a total of 6 different cases.
(btw, the expression | a < b && a > c = a is referred to as a guard. If you don't have a firm grasp yet of what guards are, then I recommend LYAH # Guards)
Of course there are better ways to write the function, but for understanding purposes it's good to be able to manually and systematically break down all of the possible situations, and determine what to do in each situation. How To Design Programs is a great book for learning how to be systematic in this way.
The obligatory Rube-Goldberg-answer:
import Control.Applicative
middleNumber a b c = sum $ [sum, negate.minimum, negate.maximum] <*> [[a,b,c]]
[Edit]
Here is another version:
middleNumber a b c = fst $ maximumBy (compare `on` abs.snd) [(a,b-c),(b,c-a),(c,a-b)]
I'm sure we could translate this to arrow syntax for further obfuscation, but I leave that task to the interested reader.
Expanding on Dan Burton's answer with guards, I evaluate a, b, c cases each in its own guard. However, what happens when 2 of the numbers are equal? Then the middle number should be one of the duplicated ones.
middleNumber :: Int -> Int -> Int -> Int
middleNumber a b c
| (a > b && a < c) || (a > c && a < b) = a
| (b > a && b < c) || (b > c && b < a) = b
| (c > a && c < b) || (c > b && c < a) = c
| otherwise = if a == b then a else c
I did a quick brute force method but this is most certainly not the best solution
import Data.List
middleNum :: Int -> Int -> Int -> Int
middleNum a b c = (\[_,m,_] -> m) $ sort $ a:b:c:[]
Obviously this is an awful idea as it explicitly relies on there being 3 items in the list, but it does the job
You can leverage guards and where to obtain the same result in simple way:
middleNumber :: Int -> Int -> Int -> Int
middleNumber x y z
| a == x = max y z
| a == y = max x z
| a == z = max x y
where
a = max x $ max y z
If you don't have access to the built-in max. you can easily write your own.
max' :: Int -> Int -> Int
max' x y
| x > y = x
| otherwise = y

Resources