列表中的元素数量大于平均值

Asa*_*saf 2 haskell

我正在尝试在Haskell
中编写一个程序,它获取一个列表(整数)并打印出大于列表平均值的元素数量

到目前为止我试过

getAVG::[Integer]->Double
getAVG x = (fromIntegral (sum x)) / (fromIntegral (length x))
smallerThanAVG:: [Integer]->Integer
smallerThanAVG x = (map (\y -> (if (getAVG x > y) then 1 else 0)) x)
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我收到了这个错误

   Couldn't match expected type `Double'
           against inferred type `Integer'
      Expected type: [Double]
      Inferred type: [Integer]
    In the second argument of `map', namely `x'
Run Code Online (Sandbox Code Playgroud)

可能是我没有正确地写出逻辑,虽然我认为我做了..
想法?

Dan*_*ton 6

这些错误是最好的,因为它们可以确定您发生类型错误的位置.

那么让我们做一些手动类型推断.让我们考虑一下这个表达式:

map (\y -> (if (getAvg x > y) then 1 else 0)) x
Run Code Online (Sandbox Code Playgroud)

我们知道一些限制:

map    :: (a -> b) -> [a] -> [b]  -- from definition
(>)    :: Num a => a -> a -> Bool -- from definition
getAvg :: [Integer] -> Double     -- from type declaration
1, 0   :: Num a => a              -- that's how Haskell works
x      :: [Integer]               -- from type declaration of smallerThanAVG
Run Code Online (Sandbox Code Playgroud)

现在让我们看看更大的表达式.

expr1 = getAvg x
expr2 = (expr1 > y)
expr3 = (if expr2 then 1 else 0)
expr4 = (\y -> expr3)
expr5 = map expr4 x
Run Code Online (Sandbox Code Playgroud)

现在让我们倒退吧.expr5与RHS相同smallerThanAVG,这意味着它与您声明的结果类型相同.

expr5 :: Integer -- wrong
Run Code Online (Sandbox Code Playgroud)

但是,这与我们的其他约束不匹配:结果map必须是[b]某些b.Integer绝对不是一个列表(虽然如果你变得滑稽,它可能被强制成一个列表).你可能意味着sum那个列表.

expr6 = sum expr5

sum :: Num a => [a] -> a
Run Code Online (Sandbox Code Playgroud)

现在让我们继续前进吧.

expr1 :: Double -- result type of getAvg
y :: Double     -- (>) in expr2 requires both inputs to have the same type
expr4 :: (Integer -> [a]) -- because for `map foo xs` (expr5)
                          -- where xs :: [a], foo must accept input a
y :: Integer    -- y must have the input type of expr4
Run Code Online (Sandbox Code Playgroud)

这里存在冲突:y不能既是一个Double和Integer.我能等效重申这是:x不能既[Double]和[Integer],这是编译器说.所以tl; dr,踢球者(>)不会比较不同类型的Nums.这类问题的模因是:"需要更多fromIntegral".

(getAvg x > fromIntegral y)
Run Code Online (Sandbox Code Playgroud)