【问题标题】:creating a function that takes a list of Ints and returns the list with any odd numbers squared创建一个函数,该函数接受一个 Ints 列表并返回具有任何奇数平方的列表
【发布时间】:2016-09-13 04:05:37
【问题描述】:

我想编写一个与使用奇数函数非常相似的过滤函数,该函数接受一个列表并返回该列表的任何奇数平方。

gchi> sqrodd [1,2,3,4,5]
[1,2,9,4,25]

我所拥有并相信是接近的

sqrodd :: (a->Bool) -> [a] -> [a]
sqrodd odd []     = []
sqrodd odd (x:xs) = if odd x
                    then (x*x) :sqrodd odd xs
                    else x : sqrodd odd xs

但函数定义出现错误,提示“无法将预期类型 a -> Bool 与实际类型 [a] 匹配”

【问题讨论】:

    标签: haskell


    【解决方案1】:

    您的sqrodd 函数有两个 参数:第一个是奇数谓词a -> Bool,第二个是元素列表[a]。在您的示例用法中,您将 [1..5] 作为 first 参数传递,以代替 a -> Bool 谓词。

    但是,您真正想要的是有两个参数,即将sqrodd 更改为单参数函数sqrodd :: [a] -> [a],然后只使用the function odd from the Prelude

    请注意,您仍然需要对sqrodd 类型进行更多限制,因为您不能将odd(*) 应用于任何类型的元素a;到达那里后,您可能需要阅读类型类以克服下一个障碍。

    【讨论】:

      【解决方案2】:

      正如您自己编写的那样,您需要一个将列表作为参数并返回另一个列表的函数,而不是具有类型签名

          sqrodd :: (a->Bool) -> [a] -> [a]
      

      您应该使用如下所示的类型签名创建一个函数

          sqrodd :: [a] -> [a]
      

      这正是你一开始写的。 由于编译器期望,该函数的第一个参数将是 (a -> bool) 的函数。 您应该从参数列表中删除奇数并更改类型签名,如上所示。这将导致函数使用前奏中的奇数,而不是期望过滤函数作为参数。

      另一种方法是将您的功能重命名为,例如 sqrfiltered,然后您可以将 sqrodd 定义为部分应用的 sqrfiltered

          sqrodd = sqrfiltered odd
      

      未测试,但应该是对的。

      【讨论】:

        【解决方案3】:

        过滤器函数检查列表中的每个元素并返回一个仅包含满足条件的元素的新列表。

        但是您想要完成的是将列表转换为新列表;新列表具有与旧列表相同数量的元素。你没有过滤掉任何东西;您正在根据某些规则将元素从一个列表映射到另一个列表。

        这里有两种可能的方式来编写你的函数。

        oddSquared, oddSquared' :: [Int] -> [Int]
        
        oddSquared l = [ if (x `mod` 2 /= 0) then x^2 else x | x <- l ]
        
        oddSquared'  = map (\x -> if odd x then x^2 else x)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-24
          • 2010-10-20
          • 2016-06-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多