将参数约束为Int

问题描述 投票:2回答:1

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

我正在编写一个函数,它将丢弃列表中的每个nth元素。我正在使用模运算,但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(我可以在输出中看到的所有约束)但这仍然不能保证编译器n将成为Int

我确信这个问题的解决方案没有使用这种命令式方法,但我想利用这个机会通过正面解决这个问题,更多地了解Haskell中的类型和约束是如何工作的。

haskell constraints
1个回答
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明确地找到列表的长度,qzxswpoi将替换你的列表理解

[ l | (l,i) <- zip list [0..], (i+1) `rem` m /= 0]
© www.soinside.com 2019 - 2024. All rights reserved.