Haskell中的I / O循环 [英] I/O Loop in Haskell

查看:191
本文介绍了Haskell中的I / O循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



编写一个函数evalpoly,它会询问用户一个单独的程度然后读入多项式的系数(从最高功率到最低值),然后读取一个值,然后输出在该值下评估的多项式的值。举例来说:

 > evalpoly 
多项式的次数是多少?3
什么是x ^ 3系数:1.0
什么是x ^ 2系数: - 2.0
什么是x ^ 1系数:0
什么是x ^ 0系数:10.0
你想估计什么值:-1.0
多项式的值是7.0

到目前为止,我有这个:

  evalpoly :: IO()
evalpoly = putStr多项式的阶数是什么:>>
getLine>> = \ xs - >
putStr什么是x ^>>
putStr(show xs)>>
putStr系数:>>
putStrLn

我该如何去添加循环和计算?

解决方案

警告:



点,并尝试自己去






不是把它全部推到这个单独的函数中,而是将它分解成更小的任务/功能。



因此,让我们从这个开始。



1。输入



显而易见的部分是要求一个值 - 如果我们在上面,我们可以确保用户输入是好的(我正在使用 Text.Read.readMaybe 为:

 查询::读取a =>字符串 - > IO 
query prompt =
putStr $ prompt ++:
val< - readMaybe< $> getLine
$ val的
没有 - > ;做
putStrLn对不起,这是一个错误的值 - 请重新输入
查询提示
只需v - >返回v
:部分,所以您不必为<$ code>提示 s






将所有问题提交给用户变得几乎微不足道:

  queryDegree :: IO Int 
queryDegree = query多项式的次数是多少ial

queryCoef :: Int - > IO(Int,Double)
queryCoef i = do
c< - query prompt
return(i,c)
where prompt =什么是x ^++显示i ++系数

queryPoint :: IO Double
queryPoint = query你想评估什么值

请注意,我将权力与系数一起提供 - 这使得计算更容易一些,但在这里我并不是绝对必要的(你可以争辩说这是更多的比功能应该在这一点上做得更好,然后使用 zip 来获得这些权力)






在您看过 mapM 以及它可以做什么 - 这是您通常希望编写循环的地方

  queryPoly :: IO [(Int,Double)] 
queryPoly = do
n< ; - queryDegree
mapM que ryCoef [n,n-1..0]



2。评估



做评估我只需要评估给定点上的每个术语(即列表中的每个 power,系数对)你可以使用 map - 在我们只需要总结这一点之后( sum 可以做到这一点):

  evaluate:Double  - > [(Int,Double)]  - > Double 
评估x =总和。 map(\(i,c)→> c * x ^ i)



3。输出



相当无聊:

  presentResult :: Double  - > ; IO()
presentResult v = putStrLn $多项式的值是++ show v



4。把它们放在一起



我只需要询问输入数据,然后评估数值然后显示出来:

 evalpoly :: IO()
evalpoly = do
p< - queryPoly
x< - queryPoint
presentResult $ evaluate xp



5。测试运行



以下是一个示例运行

 什么是多项式的次数:3 
什么是x ^ 3系数:1.0
什么是x ^ 2系数:-2.0
什么是x ^ 1系数:Hallo
对不起,这是一个错误的值 - 请重新输入
什么是x ^ 1系数:0
什么是x ^ 0系数:10.0
您想评估什么值:-1.0
多项式的值为7.0






完整的代码



请注意,我喜欢输入无缓冲,因为如果我没有它,偶尔会在Windows上遇到麻烦 - 您可能可以在没有 p>

 模块Main其中

导入Control.Monad(mapM)
导入Text.Read(readMaybe )
import System.IO(BufferMode(..),stdout,hSetBuffering)

query :: Read a =>字符串 - > IO a
query prompt = do
putStr $ prompt ++:
val< - readMaybe< $> getLine
大小写
Nothing - >做
putStrLn对不起,这是一个错误的值 - 请重新输入
查询提示
只需v - >返回v

queryDegree :: IO Int
queryDegree = query什么是多项式的阶数

queryCoef :: Int - > IO(Int,Double)
queryCoef i = do
c< - query prompt
return(fromIntegral i,c)
where prompt =什么是x ^++ show i ++系数

queryPoint :: IO Double
queryPoint = query你想评估什么值

queryPoly :: IO [ (Int,Double)]
queryPoly = do
n < - queryDegree
mapM queryCoef [n,n-1..0]

evaluate :: Double - > [(Int,Double)] - > Double
评估x =总和。 map(\(i,c) - > c * x ^ i)

presentResult :: Double - > IO()
presentResult v = putStrLn $多项式的值为++ show v

evalpoly :: IO()
evalpoly = do
p< ; - queryPoly
x< - queryPoint
presentResult $ evaluate xp


I am currently working on this Haskell problem and I seem to be stuck.

Write a function, evalpoly, that will ask a user for the degree of a single variable polynomial, then read in the coefficients for the polynomial (from highest power to lowest), then for a value, and will output the value of the polynomial evaluated at that value. As an example run:

> evalpoly
What is the degree of the polynomial: 3
What is the x^3 coefficient: 1.0
What is the x^2 coefficient: - 2.0
What is the x^1 coefficient: 0
What is the x^0 coefficient: 10.0
What value do you want to evaluate at: -1.0
The value of the polynomial is 7.0

As of now, I have this:

evalpoly :: IO ()
evalpoly  = putStr "What is the degree of the polynomial: " >>
          getLine >>= \xs ->
          putStr "What is the x^" >>
          putStr (show xs) >>
          putStr " coefficient: " >>
          putStrLn ""

How would I go about adding the loop and calculations?

解决方案

Warning:

I spoil this completely so feel free to stop at any point and try to go on yourself


Instead of pushing it all into this single function I will instead break this down into smaller tasks/functions.

So let's start with this.

1. Input

On obvious part is to ask for an value - and if we are on it we can make sure that the user input is any good (I am using Text.Read.readMaybe for this:

query :: Read a => String -> IO a
query prompt = do
  putStr $ prompt ++ ": "
  val <- readMaybe <$> getLine
  case val of
    Nothing -> do
      putStrLn "Sorry that's a wrong value - please reenter"
      query prompt
    Just v -> return v

please note that I appended the ": " part already so you don't have to do this for your prompts


having this all the questions to your user become almost trivial:

queryDegree :: IO Int
queryDegree = query "What is the degree of the polynomial"

queryCoef :: Int -> IO (Int, Double)
queryCoef i = do
  c <- query prompt
  return (i,c)
  where prompt = "What is the x^" ++ show i ++ " coefficient"

queryPoint :: IO Double
queryPoint = query "What value do you want to evaluate at"

please note that I provide the powers together with the coefficients - this make the calculation a bit easier but is not strictly necessary here I guess (you could argue that this is more than the function should do at this point and later use zip to get the powers too)


Asking all the inputs is now really easy once you've seen mapM and what it can do - it's the point where you usually would want to write a loop:

queryPoly :: IO [(Int, Double)]
queryPoly = do
  n <- queryDegree
  mapM queryCoef [n,n-1..0]

2. Evaluation

Do evaluate this I just need to evaluate each term at the given point (that is each power, coefficient pair in the list) - which you can do using map - after we just need to sum this all up (sum can do this):

evaluate :: Double -> [(Int, Double)] -> Double
evaluate x = sum . map (\ (i,c) -> c*x^i)

3. Output

Is rather boring:

presentResult :: Double -> IO ()
presentResult v = putStrLn $ "The vaule of the polynomial is " ++ show v

4. Getting it all together

I just have to ask for the inputs, evaluate the value and then present it:

evalpoly :: IO ()
evalpoly = do
  p <- queryPoly
  x <- queryPoint
  presentResult $ evaluate x p

5. Test-Run

Here is an example run

What is the degree of the polynomial: 3
What is the x^3 coefficient: 1.0
What is the x^2 coefficient: -2.0
What is the x^1 coefficient: Hallo
Sorry that's a wrong value - please reenter
What is the x^1 coefficient: 0
What is the x^0 coefficient: 10.0
What value do you want to evaluate at: -1.0
The vaule of the polynomial is 7.0


complete Code

Note that I like to enter the no-buffering because I run into trouble on Windows occasionally if I don't have it - you probably can live without

module Main where

import Control.Monad (mapM)
import Text.Read (readMaybe)
import System.IO (BufferMode(..), stdout, hSetBuffering)

query :: Read a => String -> IO a
query prompt = do
  putStr $ prompt ++ ": "
  val <- readMaybe <$> getLine
  case val of
    Nothing -> do
      putStrLn "Sorry that's a wrong value - please reenter"
      query prompt
    Just v -> return v

queryDegree :: IO Int
queryDegree = query "What is the degree of the polynomial"

queryCoef :: Int -> IO (Int, Double)
queryCoef i = do
  c <- query prompt
  return (fromIntegral i,c)
  where prompt = "What is the x^" ++ show i ++ " coefficient"

queryPoint :: IO Double
queryPoint = query "What value do you want to evaluate at"

queryPoly :: IO [(Int, Double)]
queryPoly = do
  n <- queryDegree
  mapM queryCoef [n,n-1..0]

evaluate :: Double -> [(Int, Double)] -> Double
evaluate x = sum . map (\ (i,c) -> c*x^i)

presentResult :: Double -> IO ()
presentResult v = putStrLn $ "The vaule of the polynomial is " ++ show v

evalpoly :: IO ()
evalpoly = do
  p <- queryPoly
  x <- queryPoint
  presentResult $ evaluate x p

这篇关于Haskell中的I / O循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆