我想定义一个泛型函数,它获取范围中的下一个值。我有以下函数定义:
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
答案 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
用于你认为合适的任何类型。