Function Haskell IO传递给另一个函数

Function Haskell IO传递给另一个函数,function,haskell,input,monads,Function,Haskell,Input,Monads,这里的这个问题与 我想知道如何将输入从monad IO传递到另一个函数以进行计算 实际上我想要的是 -- First Example test = savefile investinput -- Second Example maxinvest :: a maxinvest = liftM maximuminvest maxinvestinput maxinvestinput :: IO() maxinvestinput = do str <- readFile "C:\\I

这里的这个问题与

我想知道如何将输入从monad IO传递到另一个函数以进行计算

实际上我想要的是

-- First Example
test = savefile investinput 
-- Second Example
maxinvest :: a
maxinvest = liftM maximuminvest maxinvestinput

maxinvestinput :: IO()
maxinvestinput = do
    str <- readFile "C:\\Invest.txt"
    let cont = words str
    let mytuple = converttuple cont
    let myint = getint mytuple

    putStrLn ""

-- Convert to Tuple
converttuple :: [String] -> [(String, Integer)]
converttuple [] = []
converttuple (x:y:z) = (x, read y):converttuple z

-- Get Integer
getint :: [(String, Integer)] -> [Integer]
getint [] = []
getint (x:xs) = snd (x) : getint xs

-- Search Maximum Invest
maximuminvest :: (Ord a) => [a] -> a
maximuminvest [] = error "Empty Invest Amount List"
maximuminvest [x] = x
maximuminvest (x:xs)   
     | x > maxTail = x  
     | otherwise = maxTail  
     where maxTail = maximuminvest xs 
——第一个示例
测试=保存文件输入
--第二个例子
maxinvest::a
maxinvest=liftM maximuminvest maxinvestinput
MaxInput::IO()
MaxInput=do
str[(字符串,整数)]
converttuple[]=[]
converttuple(x:y:z)=(x,读取y):converttuple z
--获取整数
getint::[(字符串,整数)]->[整数]
getint[]=[]
getint(x:xs)=snd(x):getint-xs
--搜索最大投资
maximuminvest::(Ord a)=>[a]->a
maximuminvest[]=错误“空投资金额列表”
最大投资[x]=x
最大值(x:xs)
|x>maxTail=x
|否则=maxTail
其中maxTail=maximuminvest xs
在第二个示例中,从文件读取maxinvestinput并将数据转换为预期的maximuminvest类型。 请帮忙


谢谢

我不确定我是否理解你的问题,但我会尽力回答。如果我理解正确的话,我已经把事情简化了一点,以抓住问题的“核心”

maxInvestInput :: IO [Integer] maxInvestInput = liftM convertToIntegers (readFile "foo") maximumInvest :: Ord a => [a] -> a maximumInvest = blah blah blah main = do values <- maxInvestInput print $ maximumInvest values OR main = liftM maximumInvest maxInvestInput >>= print MaxInput::IO[整数] maxInvestInput=liftM转换器集成程序(读取文件“foo”) maximumInvest::Ord a=>[a]->a maximumInvest=废话废话 main=do
values>=print首先,我认为您在理解Haskell时遇到了一些基本问题,所以让我们一步一步地完成构建。希望你会觉得这很有帮助。其中一些会到达您拥有的代码,而另一些不会,但这是我在编写此代码时所考虑的一个缓慢版本。在那之后,我将试着回答你一个特别的问题


我不太确定你想让你的程序做什么。我知道你想要一个程序,它读取一个包含人员及其投资列表的文件作为输入。然而,我不知道你想用它做什么。您似乎(a)需要一个合理的数据结构(
[(String,Integer)]
),但是(b)只使用整数,所以我假设您也希望对字符串进行处理。让我们来看看这个。首先,您需要一个函数,该函数可以在给定整数列表的情况下返回最大值。您将此函数称为
maximuminvest
,但此函数比仅投资更通用,因此为什么不将其称为
maximuminvest
?事实证明,这个函数已经存在。你怎么知道的?我推荐-这是一个Haskell搜索引擎,可以让你搜索函数名和类型。您需要一个从整数列表到单个整数的函数,所以让我们来看看。事实证明,第一个结果是
最大值
,这是您想要的更通用的版本。但出于学习目的,我们假设你想自己写;在这种情况下,您的实现很好

好的,现在我们可以计算最大值。但首先,我们需要构建我们的列表。我们需要一个
[String]->[(String,Integer)]
类型的函数来将无格式列表转换为合理的列表。要从字符串中获取整数,我们需要使用
read
。长话短说,您当前的实现也很好,尽管我会(a)为一项列表添加一个
错误
案例(或者,如果我感觉不错,让它返回一个空列表来忽略奇数长度列表的最后一项),以及(b)使用一个带大写字母的名称,以便我可以区分单词(可能是另一个名字):

既然有了这些,我们就可以为自己提供一个方便的函数,
maxInvestment::[String]->Integer
。唯一缺少的是从元组列表转换为整数列表的功能。有几种方法可以解决这个问题。一种是您现有的方法,尽管这在Haskell中并不常见。第二种方法是使用
map:(a->b)->[a]->[b]
。这是一个将函数应用于列表中每个元素的函数。因此,您的
getint
相当于更简单的
map snd
。最好的方法可能是使用
Data.list.maximumBy::(a->a->Ordering)->[a]->a
。这类似于
最大值
,但它允许您使用自己的比较函数。并使用
Data.Ord.comparing::Ord a=>(b->a)->b->b->Ordering
,事情会变得很好。这个函数允许你通过将两个任意对象转换为可以比较的对象来比较它们。因此,我将编写

maxInvestment :: [String] -> Integer
maxInvestment = maximumBy (comparing snd) . tupledInvestors
尽管您也可以编写
maxInvestment=max.map snd.tupleinvestors

好的,现在进入IO。然后,您的主要函数希望读取特定文件,计算最大投资,并将其打印出来。一种表示方法是通过一系列三个不同的步骤:

main :: IO ()
main = do dataStr <- readFile "C:\\Invest.txt"
          let maxInv = maxInvestment $ words dataStr
          print maxInv
如果你还没有看过的话,
就是函数组合;
f.g
\x->f(gx)
是一样的(它的类型是
(b->c)->(a->b->a->c
,经过一些思考,这应该是有意义的。)因此,
f.g$hx
f(ghx)
相同,只是更容易阅读

现在,我们能够摆脱
let
。那么
mb)->ma->mb
操作符呢。请注意,它几乎类似于
$
,但是
m
几乎污染了所有东西。这允许我们获取一个一元值(这里是
读取文件“C:\\Invest.txt”::IO字符串
),将其传递给一个函数,该函数将普通值转换为一元值,并获取该一元值。因此,我们有

main :: IO ()
main = print . maxInvestment . words =<< readFile "C:\\Invest.txt"

这表示“从
m
中获取
x
,对其应用
f
,并将结果提升回monad。”这与
return语句相同。f=我需要创建一个函数,该函数使用monad接受IO,然后用户输入的数据将传递给另一个函数
main :: IO ()
main = do dataStr <- readFile "C:\\Invest.txt"
          print . maxInvestment $ words dataStr
main :: IO ()
main = print . maxInvestment . words =<< readFile "C:\\Invest.txt"
do x <- m
   return $ f x