我需要编写一个haskell程序,该程序提示用户输入一系列整数,每行一个整数,并以空白行结束。指示列表的末尾后,程序将查找所创建列表的中位数,并提示用户是否要再次浏览。
我花了很多时间,但是对于haskell来说是一个新手,似乎无法使我的代码编译。这是我到目前为止的内容:
module Main where
import System.IO
import Data.List
-- median.hs
-- Repeatedly prompt the user for numbers to find the median of. Ends by
-- asking the user if they want to go again. User types y to go again or
-- anything else to end the program
-- User needs to enter only a single integer on each line, ending with
-- a blank line entered. If this isn't followed the program will crash.
median = do
let list = []
putStr "This is a basic program that finds the median of a list of numbers entered."
putStr "To enter the list, enter each number individually followed by a blank line to end your list."
putStr ""
putStr "*********************************************************************************************************"
putStr "*********************************************************************************************************"
putStr ""
putStr "Begin entering the list"
putStr ""
putStr "Type a single number: "
hFlush stdout
line <- getLine
let n = read line
if (n == Nothing)
then
"No values entered, restarting program"
median
else
n:list
putStr "" --List fully entered, calculate median and print value
putStr "The median of your number is: "
let newList = createList list where
createList list = do
putStr "Type a single number or nothing to complete the list: "
hFlush stdout
input <- getLine
do
case input of
Nothing -> Nothing
x -> createList (x:list)
let med = calcMedian newList where
calcMedian :: [Integer] -> Integer
calcMedian [] = 0
calcMedian xs = result where
result = do
if (n `mod` 2 == 0) then getMiddle sorted else head $ drop a sorted where
getMiddle [] = 0
getMiddle xs = (a' + b') `div` 2 where
a' = head $ drop a xs
b' = head $ drop b xs
a = (n `div` 2)
b = n' - 1
n' = n `div` 2
n = length xs
a = (n - 1) `div` 2
n = length xs
sorted = sort xs
show med
putStr "Would you like to go again? (y or n): "
hFlush stdout
line <- getLine
let n = read line
if (line == "y")
then
median
else
return ()
main = median
答案 0 :(得分:1)
这有点太宽泛:我将只关注您阅读输入内容的第一部分。
putStr "Type a single number: "
hFlush stdout
line <- getLine
let n = read line
if (n == Nothing)
then
"No values entered, restarting program"
median
else
n:list
在这里使用字符串("No values entered, restarting program"
)和列表(n:list
)就像它们是IO操作一样,但不是。要阅读输入,我建议编写辅助递归帮助器。这是一个示例:
getNumberList :: IO [Integer]
getNumberList = do
putStr "Type a single number: "
hFlush stdout
line <- getLine
case line of
"" -> return [] -- no more numbers to read
_ -> do -- a number was entered
let n = read line
rest <- getNumberList -- recursively read the others
return (n:rest)
答案 1 :(得分:0)
n:list
不会将n
添加到列表list
的开头。它会创建一个 new 列表,该列表在索引0处包含n
,后跟列表list
。
在ghci中尝试:
let a = [] -- creates an empty list called a
0:a -- creates a new list but does nothing with the result
let b = 0:a -- creates a new list and save that value in b
现在a
的值为[]
,b
的值为[0]
答案 2 :(得分:0)
您得到的解析错误是最后代码块的结果:
let n = read line
if (line == "y")
then
median
else
return ()
由于缩进了if
构造,我认为它被解析为另一个let
绑定,如下所示:
let x = 1
y = 1 + x
并且解析器在到达main
时非常困惑。
我想也许你是说:
let n = read line
if (line == "y")
then
median
else
return ()