将参数约束为Int

时间:2019-04-03 12:15:26

标签: haskell constraints

我正在尝试声明一个函数,其中数字参数只能是Int

我正在编写一个函数,该函数将丢弃列表的第n个元素。我正在使用模算术,但是mod函数只会采用Int类型,而且我不知道如何保证我的数字会满足要求。

我的代码如下:

dropEvery :: (Num n, Eq n) => n -> [a] -> [a]
dropEvery m list = [list !! i | i <- [1 .. length list], i `rem` m /= 0]

我已经运行:info mod并将Num n替换为Real n, Enum n and Integral n(我在输出中可以看到的所有约束),但这仍然不能保证编译器使用{{1} }将是n

我确定有解决此问题的解决方案,但未使用这种命令性方法,但我想借此机会通过解决此问题来了解有关Haskell中类型和约束如何工作的更多信息-上。

1 个答案:

答案 0 :(得分:6)

您只需要使用实际类型Int,而不是使用约束(Num n, Eq n)。 (请注意,Haskell使用基于0的列表索引,因此我必须添加-1才能使其正常工作。)

dropEvery :: Int -> [a] -> [a]
dropEvery m list = [list !! (i-1) | i <- [1 .. length list], i `rem` m /= 0]

main = print $ dropEvery 3 [1..20]

Try it online!

如果您想避免使用!!,也可以避免使用zip来显式地查找列表的长度,该方法将列表理解替换为

[ l | (l,i) <- zip list [0..], (i+1) `rem` m /= 0]