用Haskell程序查找麻烦列表的中位数

时间:2019-04-27 05:00:46

标签: haskell

我需要编写一个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

3 个答案:

答案 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 ()