需要Haskell函数说明

时间:2013-12-01 16:18:09

标签: haskell

任何人都可以向我解释为什么这个功能有效。 我知道过滤器是如何工作的,它需要一个谓词函数和一个列表。 在此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)

1 个答案:

答案 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。我们寻找最大值并调用“值”(类型为bmaxVal,然后我们过滤输入列表以仅包含那些与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 值的连接方式。