我想编写一个非常类似于过滤器的函数,使用奇数函数,它接受一个列表并返回带有任何奇数平方的列表。
例如
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]相匹配”。
发布于 2016-09-13 08:09:24
当您自己编写时,您需要一个以列表作为参数并返回另一个列表的函数,所以不要使用类型签名。
sqrodd :: (a->Bool) -> [a] -> [a]您应该使用如下类型签名来创建一个函数
sqrodd :: [a] -> [a]这正是你刚开始写的。由于编译器的期望,该函数的第一个参数将是( -> bool)的函数。您应该从参数列表中删除odd,并更改类型签名,如上面所示。这将导致函数使用prelude中的奇数,而不是使用filter函数作为参数。
另一种方法是将您的函数重命名为,例如sqrfiltered,然后可以将sqrodd定义为部分应用的sqrfiltered。
sqrodd = sqrfiltered odd没有测试,但应该是对的。
发布于 2016-09-13 04:11:04
sqrodd函数有两个参数:第一个是奇怪谓词a -> Bool,第二个是元素[a]列表。在示例用法中,将[1..5]作为第一个参数传递,而不是a -> Bool谓词。
但是,您真正想要的是而不是有两个参数,即将sqrodd更改为单参数函数sqrodd :: [a] -> [a],然后只使用 from the Prelude。
请注意,在sqrodd类型中仍然需要更严格的限制,因为可以对任何类型的a元素应用odd或(*)是不正确的;您可能想在克服下一个障碍之后再阅读类型化。
发布于 2016-09-13 13:38:48
filter函数检查列表中的每个元素,并返回一个只包含满足条件的元素的新列表。
但是,您想要完成的是将列表转换为新列表;新列表具有与旧列表相同数量的元素。您没有过滤任何东西;您正在根据某些规则将元素从一个列表映射到另一个列表。
以下是编写函数的两种可能方法。
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)https://stackoverflow.com/questions/39462053
复制相似问题