替换整数或字符列表中的第n个元素,或者用户可能新定义的数据类型


replaceIthItem :: Num a => b -> [b] -> a -> [b]
replaceIthItem _ [] _ = []
replaceIthItem a (_:xs) 0 = a : xs 
replaceIthItem a (x:xs) n = x : replaceIthItem a xs (n-1)

正如标题中所提到的,该方法应该适用于任何类型的列表,上面的代码只适用于整数列表(我正在使用winhugs,我知道它很旧,但这不是问题的原因,对吧,关于Haskell,我不明白的是,它认为as integer或num总是不像prolog那样可以将变量与用户输入类型统一,那么我如何克服这个问题,并使函数类型像那样smth

replaceIthItem :: (Eq a, Num a) => t -> [t] -> a -> [t]

编辑:如果有人能为Haskell语法和函数类型的确定提供一个很好的指南,我将非常感谢,因为我在prolog上花了很多时间,无法快速适应Haskell

replaceIthItem :: Num a => b -> [b] -> a -> [b]的问题是它无法与0进行比较,因为它缺少Eq实例,正如错误可能告诉你的那样。

您提供的第二个签名replaceIthItem :: (Eq a, Num a) => t -> [t] -> a -> [t]运行良好:

λ> :{
> replaceIthItem :: (Eq a, Num a) => t -> [t] -> a -> [t]
> replaceIthItem _ [] _ = []
> replaceIthItem a (_:xs) 0 = a : xs 
> replaceIthItem a (x:xs) n = x : replaceIthItem a xs (n-1)
> :}
λ> replaceIthItem 5 [1,2,3] 1
[1,5,3]

上面代码的问题是,它仍然可以以一种荒谬的方式使用,比如在replaceIthItem 5 [1,2,3] 1.5中,正如@n.1.8e9-where’s-my-sharem所指出的那样。

如果你真的想在数字上保持多态性,你可以做replaceIthItem :: Integral a => b -> [b] -> a -> [b]。Integral带来Eq,请参阅文档。

请注意,您仍然可以给Integral a => a取负数,这对于当前的实现来说不是很明智。或者,您可以使用Numeric.Natural,它至少会为负数抛出运行时异常。例如replaceIthItem :: t -> [t] -> Natural -> [t]:

λ> replaceIthItem 5 [1,2,3] 1
[1,5,3]
λ> replaceIthItem 5 [1,2,3] 5
[1,2,3]
λ> replaceIthItem 5 [1,2,3] (-5)
<interactive>:70:28: warning: [-Woverflowed-literals]
Literal -5 is negative but Natural only supports positive numbers
*** Exception: arithmetic underflow

相关内容

最新更新