更改值succ和pred函数返回

时间:2012-05-11 07:11:31

标签: haskell

我想定义一个泛型函数,它获取范围中的下一个值。我有以下函数定义:

nextValInRange :: (Enum a) => a -> a
nextValInRange = succ

上面定义的问题是对于Fractional值,我想改变值succ函数的增量。我希望succ增加0.2而不是增加1.0。例如:

(succ 10.0) = 10.2, not 11.0

问题是我仍然希望nextValInRange函数适用于Enum类型类中的任何值。

我可以写:

nextValInRange :: (Enum a, Num a) => a -> a -> a
nextValInRange stepVal rangeVal = rangeVal + stepVal

但我不想添加Num类型限制。

我可以使用一些haskell巫毒来达到这个目的吗?

我能想到的另一个解决方案是有2个单独的nextValInRange函数,1个用于Nums,另一个用于普通枚举。

TIA

2 个答案:

答案 0 :(得分:1)

您可以修改EnumFromTo的工作方式以满足您的需求吗?除非你可以使用newtype,否则我希望你需要你自己的多态函数或你自己的类型类。

答案 1 :(得分:1)

  

我可以使用一些haskell巫毒来达到这个目的吗?

基本上,没有。您可以使用其他类型类和一些可怕的LANGUAGE编译指示,但这可能比仅为您自己的类型类定义实例更有用。

我建议使用enumFromTo作为克里斯建议,因为这解决了你正在解决的基本相同的问题。

但是,您可以将nextValInRange转换为来电者提供的功能。假设它在某些代码中使用:

makeRange :: Enum a => a -> a -> [a]
makeRange lo hi
  | lo < hi = lo : makeRange (nextValInRange lo) hi
  | otherwise = []

只需将隐式枚举字典更改为显式函数传递

即可
makeRange :: (a -> a) -> a -> a -> [a]
makeRange mySucc lo hi
  | lo < hi = lo : makeRange (mySucc lo) hi
  | otherwise = []

然后你可以传递(+ 0.1)函数用于浮点数,succ用于你认为合适的任何类型。