关于功能的Haskell问题

时间:2009-11-30 00:17:03

标签: haskell inferred-type

使用RWH,第3章问题5请求我创建了一个函数来测试是否存在paldindrome。

我写了这个,但它不起作用

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进行测试,但现在我想以我的方式找到错误。

更新:代码中的一个错误是由Justice提出的建议修正的,问题已更新以反映剩余问题

3 个答案:

答案 0 :(得分: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 :(得分:1)

两个问题。

首先,Justice指出的优先问题:您需要(take n $ reverse a)take n (reverse a)

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

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

或者,正如司法所指出的那样 - 所以请求他而不是我 - 使用整数除法div代替(/)然后你不需要toRational

(这可能有可能摆脱这些问题,但我不知道这是否值得努力......)

答案 2 :(得分:0)

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

Prelude> 2 `div` 2
1
Prelude> 3 `div` 2
1
Prelude> 4 `div` 2
2
Prelude> 5 `div` 2
2
Prelude>
相关问题
最新问题