I want to create Haskell function with different return value from its parameter, example:
I want function isOdd 3 return value either True or False.
I've tried
isOdd :: Integer -> Bool
isOdd x = (if x mod 2 == 0 False else True)
but it returns an error, can anybody help me? Also, is there a tutorial about functions in Haskell? I can't find a good tutorial about function in haskell.
isOdd :: Integer -> Bool
isOdd x = (if x mod 2 == 0 False else True)
You don't need the parens:
isOdd :: Integer -> Bool
isOdd x = if x mod 2 == 0 False else True
You missed out then:
isOdd :: Integer -> Bool
isOdd x = if x mod 2 == 0 then False else True
As you are using mod as an operator, you must surround it with backticks:
isOdd :: Integer -> Bool
isOdd x = if x `mod` 2 == 0 then False else True
That works.
Furthermore, you can write if blah then False else True more simply as not (blah):
isOdd :: Integer -> Bool
isOdd x = not (x `mod` 2 == 0)
Even more simply:
isOdd :: Integer -> Bool
isOdd x = x `mod` 2 /= 0
Please note: this is practically the same as the standard odd function.
Which tutorials have you tried?
Learn You A Haskell has a chapter introducing functions.
The problem here is that mod isn't infix. Additionally, in Haskell if statements work like this
if cond then expr1 else expr2
Notice the then.
You should use mod like this mod x 2. However you can make it infix like this:
x `mod` 2
On a side not
x `mod` 2 /= 0
Is much easier to read than the whole if statement.
As far as tutorials: Learn You a Haskell for Great Good is a good start. For a more in depth coverage Real World Haskell is excellent.
If you just want to find a function then Hoogle is your friend.
Related
i am very new to the haskell and have a question about Eq.
data Rat = Rat Integer Integer
normaliseRat :: Rat -> Rat
normaliseRat (Rat x y)
|x < 0 && y < 0 = Rat (-x) (-y)
|otherwise = Rat (x `div`(gcd x y)) (y `div` (gcd x y))
So i have a func normaliseRat. And what i need is an instance of Eq and Ord. Of course, Rat 2 4 == Rat 1 2 should be valid.
Thanks for help
Haskell doesn't support function overloading. But (==) isn't a function; it's declared as a typeclass method, so any type-specific implementations of the method must be defined within an instance declaration, like so:
instance Eq Rat where
(Rat x y) == (Rat n m) = x * m == y * n
(x/y == n/m is equivalent, after cross multiplying, to x * m == y * n; multiplication is more efficient and has none of accuracy issues that division would introduce.)
The same applies to Ord, except you have your choice of implementing (<=) or compare. (Given either of those, default definitions for the other comparison methods will work.)
instance Ord Rat where
-- I leave fixing this to accommodate negative numbers
-- correctly as an exercise.
(Rat x y) <= (Rat n m) = (x * m) <= (y * n)
As a typeclass method, (==) is really an entire family of functions, indexed by the type it's being used with. The purpose of the instance declaration is not to redefine the method, but to add a new function to that family.
If you enable the TypeApplications extension, you can view (==) as a mapping from a type to a function.
> :t (==)
(==) :: Eq a => a -> a -> Bool
> :t (==) #Int
(==) #Int :: Int -> Int -> Bool
Without a type application, Haskell's type checker automatically figures out which function to use:
> (==) 'c' 'd'
False
> (==) 3 5
False
but you can be explicit:
> (==) #Char 'c 'd'
False
> (==) #Char 3 5
<interactive>:9:12: error:
• No instance for (Num Char) arising from the literal ‘3’
• In the second argument of ‘(==)’, namely ‘3’
In the expression: (==) #Char 3 5
In an equation for ‘it’: it = (==) #Char 3 5
I am working on the following exercise:
Define a function libDiv which computes the list of natural divisors of some positive integer.
First define libDivInf, such that libDivInf n i is the list of divisors of n which are lesser than or equal to i
libDivInf : int -> int -> int list
For example:
(liDivInf 20 4) = [4;2;1]
(liDivInf 7 5) = [1]
(liDivInf 4 4) = [4;2;1]
Here's is my attempt:
let liDivInf : int -> int -> int list = function
(n,i) -> if i = 0 then [] (*ERROR LINE*)
else
if (n mod i) = 0 (* if n is dividable by i *)
then
i::liDivInf n(i-1)
else
liDivInf n(i-1);;
let liDiv : int -> int list = function
n -> liDivInf n n;;
I get:
ERROR: this pattern matches values of type 'a * 'b ,but a pattern
was expected which matches values of type int
What does this error mean? How can I fix it?
You've stated that the signature of liDivInf needs to be int -> int -> int list. This is a function which takes two curried arguments and returns a list, but then bound that to a function which accepts a single tuple with two ints. And then you've recursively called it in the curried fashion. This is leading to your type error.
The function keyword can only introduce a function which takes a single argument. It is primarily useful when you need to pattern-match on that single argument. The fun keyboard can have multiple arguments specified, but does not allow for pattern-matching the same way.
It is possible to write a function without using either.
let foo = function x -> x + 1
Can just be:
let foo x = x + 1
Similarly:
let foo = function x -> function y -> x + y
Can be written:
let foo x y = x + y
You've also defined a recursive function, but not included the rec keyword. It seems you're looking for something much more like the following slightly modified version of your attempt.
let rec liDivInf n i =
if i = 0 then
[]
else if (n mod i) = 0 then
i::liDivInf n (i-1)
else
liDivInf n (i-1)
I seem to be stuck on a question and have no idea how to approach it or what Im doing wrong with my current code.
I have to write a function called oddDigits which takes a single integer argument and returns a boolean result. It should return True if and only if the argument is a positive integer with an odd number of digits. If the argument is zero or negative, the function should stop with an error message.
Also, cant convert the argument into a string. Have to use recursion.
I have a feeling each digit could be stored in a list recursively and then the length of the list could determine the answer.
So far, I have this:
oddDigits :: Integer -> Bool
lst = []
oddDigits x
| (x < 0) || (x == 0) = error
| x `mod` 10 ++ lst ++ oddDigits(x `div` 10)
| length(lst) `mod` 2 /= 0 = True
| otherwise = False
Sorry if the code looks horrible. I am new to Haskell and still learning. What exactly am I doing wrong and how could I correct it?
First off, this seems a pretty weird thing to check. Perhaps what you're doing wrong is to ever consider this problem...
But if you persist you want to know the property of an integer having an odd number of digits... oh well. There's a lot that could be improved. For starters, (x < 0) || (x == 0) doesn't need the parentheses – < and == (infix 4) bind more tightly than ||. If you're not sure about this, you can always ask GHCi:
Prelude> :i ==
class Eq a where
(==) :: a -> a -> Bool
...
-- Defined in ‘GHC.Classes’
infix 4 ==
Prelude> :i ||
(||) :: Bool -> Bool -> Bool -- Defined in ‘GHC.Classes’
infixr 2 ||
But here you don't need || anyway because there's a dedicated operator for less-than-or-equal. Hence you can just write
oddDigits x
| x <= 0 = error "bla bla"
| ...
Then, you can “convert” the number to a string. Converting to string is generally a really frowned-upon thing to do because it throws all structure, typechecking etc. out of the window; however “number of digits” basically is a property of a string (the decimal expansion), rather than a number itself, so this is not entirely unsensible for this specific task. This would work:
oddDigits x
| x <= 0 = error "blearg"
| length (show x)`mod`2 /= 0 = True
| otherwise = False
however it's a bit redundancy department redundant. You're checking if something is True, then give True as the result... why not just put it in one clause:
oddDigits x
| x <= 0 = error "blearg"
| otherwise = length (show x)`mod`2 /= 0
That's perhaps in fact the best implementation.
For any proper, sensible task, I would not recommend going the string route. Recursion is better. Here's what it could look like:
oddDigits 1 = True
oddDigits x
| x <= 0 = error "blearg"
| otherwise = not . oddDigits $ x`div`10
There's nothing wrong with your general approach of converting to a list of digits, then finding the length of the list. Really where you went wrong is trying to cram everything into one function. As you found out first hand, it makes it very difficult to debug. Functional programming works best with very small functions.
If you separate out the responsibility of converting an integer to a list of digits, using a digs function like the one from this answer, the rest of your algorithm simplifies to:
oddDigits x | x <= 0 = error
oddDigits x = odd . length $ digs x
leftaroundabout's eventual answer is very nice, however it fails for numbers like 2,3 and 23. Here's a fix.
oddDigits x
| x <= 0 = error "blearg"
| x < 10 = True
| otherwise = not . oddDigits $ x`div`10
Its much more elegant than my initial answer, below. I'm including it to introduce a common functional paradigm, a worker/wrapper transformation of the problem. Here the wrapper gives the interface and passes off the work to another function. Notice that the negativity check only needs to be done once now.
oddDigits :: Integer -> Bool
oddDigits x
| x <= 0 = False
| otherwise = oddDigits' True x
oddDigits' :: Bool -> Integer -> Bool
oddDigits' t x
| x < 10 = t
| otherwise = oddDigits' (not t) $ x `div` 10
oddDigits' carries a piece of internal data with it, the initial Bool. My first first thought was to have that Bool be a digit accumulator, counting the number of digits. In that case, an "unwrapper" needs to be supplied, in this case the standard "odd" function:
oddDigits x
| x <= 0 = False
| otherwise = odd . oddDigits'' 1 $ x
where oddDigits'' :: Integer -> Integer -> Integer.
I wrote the GNU Fortran code in two separate files on Code::Blocks: main.f95, example.f95. main.f95 content:
program testing
use example
implicit none
integer :: a, b
write(*,"(a)", advance="no") "Enter first number: "
read(*,*) a
write(*,"(a)", advance="no") "Enter second number: "
read(*,*) b
write(*,*) factorial(a)
write(*,*) permutation(a, b)
write(*,*) combination(a, b)
end program testing
example.f95 content:
module example
contains
integer function factorial(x)
implicit none
integer, intent(in) :: x
integer :: product_ = 1, i
if (x < 1) then
factorial = -1
else if (x == 0 .or. x == 1) then
factorial = 1
else
do i = 2, x
product_ = product_ * i
end do
factorial = product_
end if
end function factorial
real function permutation(x, y)
implicit none
integer, intent(in) :: x, y
permutation = factorial(x) / factorial(x - y)
end function permutation
real function combination(x, y)
implicit none
integer, intent(in) :: x, y
combination = permutation(x, y) / factorial(y)
end function combination
end module example
When I run this code, the output is:
Enter first number: 5
Enter second number: 3
120
0.00000000
0.00000000
The permutation and combination functions don't work properly. Thanks for answers.
I think you've fallen foul of one of Fortran's well-known (to those who know it) gotchas. But before revealing that I have to ask how much testing you did ? I ran your code, got the odd result and thought for a minute ...
then I tested the factorial function for a few small values of x which produced
factorial 1 = 1
factorial 2 = 2
factorial 3 = 12
factorial 4 = 288
factorial 5 = 34560
factorial 6 = 24883200
factorial 7 = 857276416
factorial 8 = -511705088
factorial 9 = 1073741824
factorial 10 = 0
which is obviously wrong. So it seems that you didn't test your code properly, if at all, before asking for help. (I didn't test your combination and permutation functions.)
O tempora, o mores
You've initialised the variable product_ in the line
integer :: product_ = 1, i
and this automatically means that product_ acquires the attribute save so its value is stored from invocation to invocation (gotcha !). At the start of each call (other than the first) product_ has the value it had at the end of the previous call.
The remedy is simple, don't initialise product_. Change
integer :: product_ = 1, i
to
integer :: product_ , i
...
product_ = 1
Simpler still would be to not write your own factorial function but to use the intrinsic product function but that's another story.
I have this code:
esprimo :: Int->Bool
esPrimo x = if length (div x x) == 2 then True else False
But I pulled the error is above
In addition to what sibi said, I think what you are trying to do is this:
isPrime :: Int -> Bool
isPrime x = if length [d | d <- [1..x], x `mod` d == 0] == 2 then True else False
this is basically the direct translation of the mathematical concept of beeing prime into Haskell.
As you don't need the if as it checks the same == already returns a bit more readable might be:
isPrime :: Int -> Bool
isPrime x = length divisors == 2
where divisors = [d | d <- [1..x], x `isMultipleOf` d]
isMultipleOf m n = m `mod` n == 0
Please note that this is of course not the most performant prime-test.
The exact reason for your error is because of the different cases you have used in the type signature and the type definition:
esprimo :: Int -> Bool -- p should be capital here to work.
esPrimo x = if length (div x x) == 2 then True else False
Haskell is case sensitive, so esprimo and esPrimo are different. That being said there is other type error in your code: the type of div is div :: Integral a => a -> a -> a, so it returns a and you are applying length function on it. But length function only accepts list i.e [a] and not a which will produce you type error.