Function 用户输入的平均值

Function 用户输入的平均值,function,haskell,average,Function,Haskell,Average,我想让用户输入一个数字列表,然后找到平均值。然而,在查找示例之后,我没有发现任何与我所做的匹配的示例,因为我可以在列表中找到2-100个数字。欢迎提供任何帮助/建议 下面是我的工作代码 main = do putStrLn "Enter how many numbers:" listlen <- getLine if ((read listlen) <= 100) -- read converts a string to a number then do

我想让用户输入一个数字列表,然后找到平均值。然而,在查找示例之后,我没有发现任何与我所做的匹配的示例,因为我可以在列表中找到2-100个数字。欢迎提供任何帮助/建议

下面是我的工作代码

main = do
  putStrLn "Enter how many numbers:"
  listlen <- getLine 
  if ((read listlen) <= 100) -- read converts a string to a number
  then do  

  putStrLn "Enter a String of numbers:"
  --numberString <- getLine

  numberString<- getLine
  let ints = map read (words numberString)  :: [Int]
  putStrLn("The List: " ++(numberString))

  putStrLn("The average: ")
  putStrLn("Number of values greater than average: ")

  else do
    putStrLn " Error: listlen must be less than or = to 100"
    main
main=do
putStrLn“输入多少个数字:”
listlen
listlen::[a]->Int
listlen xs=go 0 xs--0=累加器的初始值
其中go s[]=s——返回累加器
go s(a:as)=go(s+1)as——计算累加器的下一个值
sumx::[a]->Int
sumx xs=go 0 xs
去哪里s[]=s
go s(a:as)=go。。。如同空白的空白……和递归
lenAndSum::[a]->(Int,Int)
lenAndSum xs=go(0,0)xs--(0,0)=两个蓄能器的初始值
其中go(s1,s2)[]=(s1,s2)——在末端返回两个蓄能器
去(s1,s2)(a:as)=去。。。作为一种练习
main=do
putStrLn“输入多少个数字:”

listlen好的,这是家庭作业,但当你不得不在Haskell做作业时,家庭作业可能会很难。我将试着一步一步地解释你能做什么

很高兴知道 首先,Haskell是功能性的。你可以找到“functional”的不同定义,但基本上你可以把它看作是语言的一种属性:一切都是不变的(没有副作用)

其次,您可以通过在终端中键入
ghci
来启动:

jferard@jferard-Z170XP-SLI:~$ ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Prelude> :set +m -- enable parsing of multiline commands
Prelude> -- type the expression you want to evaluate here
递归 如何计算列表中元素的总和?在命令式语言中,您将执行类似于Python的操作:

只要稍加想象,你就可以说
sum[]=0
。所以我们可以用Haskell来写:

sum [] = 0
sum (x:xs) = x + sum xs

-- sum [1, 2, 3, 5] == 11
(x:xs)
的意思是:
x
head
),后面是列表
xs
tail
)。如果您已经理解了这一点,您就知道在许多情况下如何避免副作用:只需调用另一个函数来完成其余的工作。(注意:如果您了解堆栈,可以想象引擎盖下会发生什么。)

现在,如何计算列表的长度?在类似Python的语言中,您可以执行以下操作(忘记
len(…)
):

褶皱 计算总和和长度非常常见,因此它们是Haskell中的内置函数。但有一点更重要:如果仔细检查这两个函数,您会注意到以下模式:

f [] = <initial value>
f (x:xs) = g(f xs, x)
(关于curryfication的注意事项:1.有一天您可能会了解到Haskell函数总是使用一个参数,但这不是重点。2.您可以删除两边的X:
sum=foldl(+)0

使用
scanl
,您可以通过某种方式“调试”
foldl

Prelude> scanl (+) 0 [1,2,3,5]
[0,1,3,6,11]
gtAvg xs = foldl (\acc x -> if fromIntegral x>average xs then acc+1 else acc) 0 xs
length
更复杂,因为您没有内置函数
g(f xs,x)=1+f xs
。您可以使用:
\acc x->1+acc
,其中
acc
是当前值:

length xs = foldl (\acc x -> 1 + acc) 0 xs
你的问题 平均的 让我们尝试使用内置的
sum
length
函数编写
average

Prelude> average xs = sum xs / length xs

<interactive>:1:14: error:
    • Could not deduce (Fractional Int) arising from a use of ‘/’
    ...
这意味着
/
将采用
分数
s。因此,工作是:将整数转换成分数

average xs = fromIntegral (sum xs) / fromIntegral (length xs)

-- average [1, 2, 3, 5] == 2.75
大于平均值的值的数目 现在,值的数量大于平均值。在类似Python的语言中,您将编写:

c = 0
for every x in xs:
    if x > avg:
        c <- c + 1

你看,有东西不见了。在命令式版本中,如果
x是这样,您发现了什么看起来很接近但并不完美的匹配?为什么你认为它对你不起作用?这里的很多人都可以为你写一个解决方案,但是为了帮助你学习,看看你在想什么和你尝试过什么是很重要的。我试过以下方法:--但是我不知道如何将它用于最多100个可以输入的数字我已经看过了这里几乎所有的Haskell average相关帖子,似乎没有一篇文章的长度是基于用户输入的。。所以我不能硬编码长度。第一个链接对于任何大小的列表都可以,不管是否由用户给出。这看起来像是一个家庭作业问题。向你的教授或助教寻求帮助可能更合适。当然,你走对了方向。有一些有效的方法可以填补这些空白来回答您的问题(不过,您必须修复这些类型)。另外,要小心剽窃:虽然Stack Overflow不介意您使用其答案中的代码,但Stack Overflow的授权和您的教授都会要求您引用您使用的任何非您自己的代码。另外,您已经认为您知道列表的长度,因此不必计算它。
Prelude> foldl (+) 0 [1,2,3,5]
11 -- (((0+1)+2)+3)+5
Prelude> scanl (+) 0 [1,2,3,5]
[0,1,3,6,11]
length xs = foldl (\acc x -> 1 + acc) 0 xs
Prelude> average xs = sum xs / length xs

<interactive>:1:14: error:
    • Could not deduce (Fractional Int) arising from a use of ‘/’
    ...
Prelude> :t (/)
(/) :: Fractional a => a -> a -> a
average xs = fromIntegral (sum xs) / fromIntegral (length xs)

-- average [1, 2, 3, 5] == 2.75
c = 0
for every x in xs:
    if x > avg:
        c <- c + 1
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1) + sum xs -- WRONG
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1 else 0) + gtAvg xs
gtAvg' [] _ = 0
gtAvg' (x:xs) avg = (if fromIntegral x>avg then 1 else 0) + gtAvg' xs avg

-- gtAvg' [1, 2, 3, 5] (average [1, 2, 3, 5]) == 2
gtAvg xs = gtAvg' xs (average xs)

-- gtAvg [1, 2, 3, 5] == 2
gtAvg xs = foldl (\acc x -> if fromIntegral x>average xs then acc+1 else acc) 0 xs
Prelude> filter (>2.75) [1, 2, 3, 5]
[3.0,5.0]
gtAvg xs = length $ filter (\x -> fromIntegral x >average xs) xs
Prelude> sum $ map (**2)  [1, 2, 3, 5]
39.0
gtAvg xs = length $ filter (>average xs) $ map fromIntegral xs
gtAvg xs = length [x | x<-xs, fromIntegral x>average xs]