Haskell question about function
Working out of RWH, Chapter 3 question 5 requests I create a function to test for the existence of a paldindrome.
I wrote this, but it doesn't work
pCheck :: (Eq a) => [a] -> Bool;
pCheck a = take n a == ( take n $ reverse a )
where n = floor ( length a / 2 )
I get this error when I try to run it:
No instance for (RealFrac Int)
arising from a use of `floor' at len.hs:13:11-32
Possible fix: add an instance declaration for (RealFrac Int)
In the expression: floor (length a / 2)
In the definition of `n': n = floor (length a / 2)
In the definition of `pCheck':
pCheck a = take n a 开发者_StackOverflow== (take n $ reverse a)
where
n = floor (length a / 2)
I'm confused what am I doing wrong? I know a paldindrome could just as well be tested with a == reverse a
, but now I want to find the error in my way.
UPDATE: one of the errors with the code was fixed by a suggestion by Justice, the question has been updated to reflect the remaining problem
The expression
take n a == take n $ reverse a
gets parsed as
(take n a == take n) $ (reverse a)
because the $
operator has precedence 0
, lower even than the ==
operator.
You need the expression:
take n a == (take n $ reverse a)
Also, please respect the Haskell and use length a
rather than length (a)
. You should also use length a `div` 2
rather than length a / 2
. The function div
is integer division, resulting in an integer.
Two problems.
First, the precedence problem noted by Justice: you need (take n $ reverse a)
or take n (reverse a)
Second, you can only divide rationals, not integers, so you really want
where n = floor $ (toRational $ length $ reverse a) / 2
Or, as noted by Justice -- so upvote him rather than me for this -- use integer division div
instead of (/)
and then you don't need toRational
(It might be possible to get rid of the parens here, but I don't know if it's worth the effort...)
Haskell won't do any kind of automatic conversion between integral and floating point numbers when it sees expressions like length a / 2
. If you want to divide 2 numbers of type Int
ignoring any remainders, use div
.
Prelude> 2 `div` 2
1
Prelude> 3 `div` 2
1
Prelude> 4 `div` 2
2
Prelude> 5 `div` 2
2
Prelude>
精彩评论