任何人都可以向我解释为什么这个功能有效。
我知道过滤器是如何工作的,它需要一个谓词函数和一个列表。
在此def maximaBy valueFcn xs = filter isMaxVal
xs
filter将isMaxVal作为谓词,xs是列表。
但我无法理解
where
isMaxVal xs = valueFcn xs == maxVal
Here isMaxVal is defined as a function that takes xs as an argument but how is that possible xs is an agrument of filter.
if we change valueFcn to function length
we get
isMaxVal xs = length xs == maxVal
if xs is ["cs", "efd", "lth", "it"] length of this is 4 but maxVal ==3
maxVal = maximum (map length ["cs", "efd", "lth", "it"]) ==3
-- maximaBy length ["cs", "efd", "lth", "it"] == ["efd", "lth"]
maximaBy :: Ord b => (a -> b) -> [a] -> [a]
maximaBy valueFcn xs = filter isMaxVal xs
where
isMaxVal xs = valueFcn xs == maxVal
maxVal = maximum (map valueFcn xs)
答案 0 :(得分:1)
过滤器由filter p (x:xs) = x : (filter p xs)
的概念定义,当且仅当 p x == True
时。因此它过滤输入列表以仅包含满足谓词p
的元素。
在这种情况下,只有当输入True
计算的值等于valueFcn :: Ord b => (a -> b)
时,我们才会将谓词定义为maxVal :: b
,无论maxVal
是什么。< / p>
在下一行,我们将maxVal
的定义定义为maximum
按行分组(“映射”)修改的输入列表的valueFcn
。
因此,在每种情况下,我们都会查看输入值“到”valueFcn
,这会产生某种我们可以比较的值Ord b => b
。我们寻找最大值并调用“值”(类型为b
)maxVal
,然后我们过滤输入列表以仅包含那些与maxVal
匹配的输入{{1为他们计算。
更清楚的是,这是解决问题的另一种方法。我们希望通过valueFcn
的输出来评估每个输入,因此我们将这些值折叠起来。给定valueFcn
我们写
valueFcn :: Ord b => a -> b
然后我们在列表上传递一次,查找每个元组的第二个组件的最大值。
let pairs = map (\x -> (x, valueFcn x)) :: Ord b => [a] -> [(a, b)]
这是一个最大输入及其各自的值,但我们尚未完成,因为我们认为此值可能会在输入列表中重复出现,因此我们再次搜索列表以查找与该值匹配的任何内容
let (maxInput, maxValue) = maximumBy (\a b -> compare (snd a) (snd b)) pairs
然后我们只返回到目前为止的输入,而不是它们的let results :: Ord b => [(a, b)]
results = filter (\x -> snd x == maxValue) pairs
值。
valueFcn
此方法实际上比您的函数使用的方法略显笨拙,但它以略微不同的方式突出显示输入值及其map fst results
值的连接方式。