包含递归和高阶函数的Haskell列表

时间:2017-10-21 05:26:34

标签: list function haskell recursion

现在我有了这个代码,它接受一个列表并对第一个元素执行某些操作,然后对其他元素执行某些操作。它返回转换元素的列表。我遇到的问题是我想要一个包含未转换元素和转换元素的列表。这就是我到目前为止所做的:

applyToEveryOther :: (a -> b) -> [a] -> [b]
applyToEveryOther _ [] = []
applyToEveryOther f [x] = [f x]
applyToEveryOther f (x:y:xs) = f x : y : applyToEveryOther f xs

它给我的错误说明函数的: y部分存在问题

2 个答案:

答案 0 :(得分:4)

当我尝试使用您的代码时,我会收到以下信息(确实有些冗长且令人困惑)错误消息:

EveryOther.hs:4:42: error:
    • Couldn't match type ‘b’ with ‘a’
      ‘b’ is a rigid type variable bound by
        the type signature for:
          applyToEveryOther :: forall a b. (a -> b) -> [a] -> [b]
        at EveryOther.hs:1:22
      ‘a’ is a rigid type variable bound by
        the type signature for:
          applyToEveryOther :: forall a b. (a -> b) -> [a] -> [b]
        at EveryOther.hs:1:22
      Expected type: [a]
        Actual type: [b]
    • In the second argument of ‘(:)’, namely ‘applyToEveryOther f xs’
      In the second argument of ‘(:)’, namely
        ‘y : applyToEveryOther f xs’
      In the expression: f x : y : applyToEveryOther f xs
    • Relevant bindings include
        xs :: [a] (bound at EveryOther.hs:4:26)
        y :: a (bound at EveryOther.hs:4:24)
        x :: a (bound at EveryOther.hs:4:22)
        f :: a -> b (bound at EveryOther.hs:4:19)
        applyToEveryOther :: (a -> b) -> [a] -> [b]
           (bound at EveryOther.hs:2:1)

然而,值得一试的是想知道GHC在这里说的是什么。根据第二个要点,GHC正在处理子表达式y : applyToEveryOther f xs,并专门查看该表达式中:运算符的第二个参数(即applyToEveryOther f xs。它期望表达式具有键入[a],但表达式的实际类型为[b]类型。

此处,ab都是"刚性"类型,意思是它们是由程序员明确指定的。 GHC还在相关的约束中指出,y具有类型a

总而言之,你要求GHC评估表达式:

y : applyToEveryOther f xs

您已指定y类型为aapplyToEveryOther f xs类型为[b],而GHC拒绝这样做,因为Haskell中的列表无法混合两种不同的类型。

这就是整个问题的关键。您希望将[a]列表的某些元素从a转换为b,但是您想要返回a和{{1}的混合列表}秒。哈斯克尔不能这样做!

您的功能可以使用的唯一方法是更改​​签名,以便ba属于同一类型:

b

您的代码将正常运行。

你可以发现的另一种方式"正确的签名是将其遗漏并让Haskell推断出最普​​遍的签名。如果您将代码(没有显式签名)加载到GHCi中并询问类型,则会得到:

applyToEveryOther :: (a -> a) -> [a] -> [a]

这是此功能最常用的类型。

答案 1 :(得分:0)

如果我理解正确,你想要两者,原始值和转换值。

但是评估applyToEveryOther (+3) [0,1,2]会返回[3,1,5]。如果您想要[0,3,1,4,2,5],请尝试

applyToEveryOther _ [] = []
applyToEveryOther f [x] = [x,f x]
applyToEveryOther f (x:xs) = x: f x : applyToEveryOther f xs