List 满足haskell中大多数元素的函数

List 满足haskell中大多数元素的函数,list,function,haskell,List,Function,Haskell,我需要编写一个代码,如果函数满足列表中的大多数元素,则会给出True,如果函数中的false不满足,则会给出false。 例如:大于奇数[1,2,3]为真,但大于奇数[1,2,3,4]为假。 这是我的密码: moreThan funkt xs = let control funkt n (x : xs) = control (if .?. then n + 1 else n) xs contol funkt _ = False

我需要编写一个代码,如果函数满足列表中的大多数元素,则会给出True,如果函数中的false不满足,则会给出false。 例如:
大于奇数[1,2,3]
,但
大于奇数[1,2,3,4]
。 这是我的密码:

moreThan funkt xs
   = let
      control funkt n (x : xs)
         = control (if .?. then n + 1 else n) xs
      contol funkt _
         = False
   in
   control funtk 0 xs
有人能告诉我如何控制它,我应该在
中写些什么吗?

谢谢

您编写的函数将为所有参数返回
False
,因为列表结束时您总是返回
False

您编写的函数需要跟踪两个变量:已处理的元素数和谓词为true的元素数。因为这段代码可能是家庭作业,所以我给你一个可以用来编写函数的结构。在
-->
位置填写您自己的代码

moreThan :: (a -> Bool) -> [a] -> Bool
moreThan pred = go 0 0 where
  -- procd: number of elements processed
  -- holds: number of elements for which pred holds
  go procd holds (x:xs) = go procd' holds' xs where
     procd' = -- ???
     holds' = -- ???
  go procd holds []     = -- ???
如果您需要更多提示,请随时发表评论


编写此函数的更惯用方法是使用折叠:

moreThan pred = finalize . foldr go (0,0) where
  -- process one element of the input, produce another tuple
  go (procd,holds) x = -- ???
  -- produce a boolean value from the result-tuple
  finalize (procd,holds) = -- ???

也许不是最有效的解决方案,但肯定是一个非常明确的解决方案,如下所示:

moreThan :: (a -> Bool) -> [a] -> Bool
moreThan f xs = length ts > length fs where
    ts = filter id bools
    fs = filter not bools
    bools = map f xs
了解你的图书馆

import Data.List(partition)
import Data.Function(on)

moreThan f = (uncurry $ on (>) length) . partition f
如果不允许使用分区,请自己编写:

part f xs = (filter f xs, filter (not.f) xs)
或者用数字的方式:

moreThan f xs = 2*s > length xs where s = sum $ map (fromEnum.f) xs

我希望这是有效的(只遍历列表一次),但仍然相当清晰

majority :: (a -> Bool) -> [a] -> Bool
majority pred = g . sum . map f
  where f x | pred x    = 1
            | otherwise = -1
        g y = 0 < y
多数::(a->Bool)->[a]->Bool
多数pred=g。总和地图f
其中f x | pred x=1
|否则=-1
Gy=0
多数::(a->Bool)->[a]->Bool
多数p=(如果pred x为0,则为1,否则为-1)

这是对列表元素的映射(如果pred x那么1 else-1),然后对列表元素求和,并查看结果是否大于0。

moreThan=(\(lTrue,lFalse)->length lTrue>length lFalse)。分区
会更惯用一些。好吧,如果你只是使用一个
let
,而不是抛出一个随机的毫无意义的lambda,那会更惯用一些。好吧,首先,我必须问:这是家庭作业吗?如果是这样的话,应该用[家庭作业]标记。不,我有一个哈斯克尔初级考试,我正在努力准备。所以,我不知道如何解决这个问题,如果你能演示一下,我将非常高兴。@leftaroundabout:那么更性感的
(>>>)uncurry(>)是一个不好的选择。你只需要跟踪一件事,计数的差异。
(>0)。foldl'(\nx->如果px,则n+1,否则n-1)“0
是我认为惯用的。@Daniel Fischer关于foldr uniodeomatic的定义是什么?单计数器的想法很好。我不是说,
foldr
是unidiomatic的(尤其不是一般的)更新函数在两个参数中都是严格的,结果与列表元素的处理顺序无关,这对于
foldl'
来说是一个明显的例子。
majority :: (a -> Bool) -> [a] -> Bool
majority p = (0 <) . sum . map (\x -> if pred x then 1 else -1)