2009-11-30 44 views
2

RWH,第3章问题5请求的工作我创建了一个函数来测试paldindrome的存在。关于函数的Haskell问题

我写了这一点,但它不工作

pCheck :: (Eq a) => [a] -> Bool; 
pCheck a = take n a == (take n $ reverse a) 
    where n = floor (length a/2) 

我得到这个错误,当我尝试运行它:

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 == (take n $ reverse a) 
      where 
       n = floor (length a/2) 

我很困惑我究竟做错了什么?我知道一个paldindrome可以用a == reverse a进行测试,但现在我想以我的方式找到错误。

UPDATE:与代码中的错误之一是固定的,通过司法建议,这个问题已经被更新,以反映剩下的问题

+0

一个简单测试将是:'isPalindrome X =(秀X)==(反向$显示X)' – 2009-11-30 06:37:13

+0

回复:Jonno,我不认为节目,或需要括号。 'isPalindrome = x ==反向x' – 2009-11-30 06:52:40

回答

5

表达

take n a == take n $ reverse a 

被解析为

(take n a == take n) $ (reverse a) 

因为$运营商优先0,甚至低于==运营要么。

你需要表达:

take n a == (take n $ reverse a) 

此外,请尊重Haskell和使用length a而非length (a)。您还应该使用length a `div` 2而不是length a/2。函数div是整数除法,产生一个整数。

1

两个问题。

首先,优先问题,通过司法注意:您需要(take n $ reverse a)take n (reverse a)

其次,你只能划分有理数,不是整数,所以你真的想

where n = floor $ (toRational $ length $ reverse a)/2 

或者由法官表示 - 所以upvote他而不是我为此 - 使用整数除div而不是(/),然后你不需要toRational

(这可能是可能的在这里摆脱parens,但我不知道是否值得这个努力......)

0

当看到像length a/2这样的表达式时,Haskell将不会在积分和浮点数之间进行任何类型的自动转换。如果要分割2个Int类型的数字而忽略其余的数字,请使用div

Prelude> 2 `div` 2 
1 
Prelude> 3 `div` 2 
1 
Prelude> 4 `div` 2 
2 
Prelude> 5 `div` 2 
2 
Prelude>