nic*_*las 4 io haskell interactive
我想知道IO()函数可以返回元组,因为我想将这些函数作为另一个函数的输入.
investinput :: IO()->([Char], Int)
investinput = do
putStrLn "Enter Username : "
username <- getLine
putStrLn "Enter Invest Amount : "
tempamount <- getLine
let amount = show tempamount
return (username, amount)
Run Code Online (Sandbox Code Playgroud)
请帮忙.
谢谢.
Haskell中的IO在您习惯使用的语言中不像IO那样工作.Haskell中的所有函数都必须是纯粹的:也就是说,如果f使用参数调用函数x,则调用它一次,两次或一百次之间必须没有区别.考虑一下这对IO意味着什么.天真地,getLine应该有类型getLine :: String,或者也许getLine :: () -> String.(()是单位类型,它的唯一值是();它有点像C语言中的void类型,但它有一个值.)但这意味着每次你写getLine,它都必须返回在相同的字符串,这是不是你想要的.这是IO类型的目的:封装动作.这些行动与功能不同; 它们代表不纯的计算(虽然它们本身就是纯粹的).type的值IO a表示一个操作,该操作在执行时返回type的值a.因此,getLine具有类型getLine :: IO String:每次评估动作时,String产生a(通过从用户读取).同样,putStr有类型putStr :: String -> IO (); 它是一个函数,它接受一个字符串并返回一个动作,当它运行时,它不会返回任何有用的信息......但是,作为副作用,它会向屏幕输出一些内容.
您正在尝试编写类型的函数IO () -> ([Char], Int).这将是一个函数,它将一个动作作为输入并返回一个元组,这不是你想要的.你想要一个IO (String, Int)-an动作,它在运行时会产生一个由字符串(它是一个同义词[Char])和一个整数组成的元组.你的当前代码也差不多了!这就是你需要的:
investinput :: IO (String, Int)
investinput = do
putStrLn "Enter Username : "
username <- getLine
putStrLn "Enter Invest Amount : "
tempamount <- getLine
let amount = read tempamount
return (username, amount)
Run Code Online (Sandbox Code Playgroud)
请注意,我只进行了两次更改(并删除了一个空行).首先,我已经改变了函数的类型,就像我上面说的那样.其次,我改变show了read.该show函数具有以下类型Show a => a -> String:它是一个函数,它接收可以显示的任何内容并生成表示它的字符串. 你想要的read,它有类型Read a => String -> a:给定一个字符串,它解析它并返回一些可读的值.
你问的另一件事是返回一个元组(String, Int)而不是一个动作IO (String, Int).没有纯粹的方法可以做到这一点; 换句话说,没有纯粹的功能IO a -> a.为什么是这样?因为IO a代表了一种取决于现实世界的不纯净的行为.如果我们有这样的函数impossibleRunIO :: IO a -> a,那么我们希望它是这样的impossibleRunIO getLine == impossibleRunIO getLine,因为函数必须是纯的.但这没用,因为我们希望impossibleRunIO能够真实地与现实世界互动!因此,这种纯粹的功能是不可能的.进入的一切IO都永远不会离开.这就是return:它是一个函数,在这种情况下为1,类型return :: a -> IO a,使您可以将纯值放入IO.对于任何x,return x是一种在运行时始终产生的动作x.这就是为什么你必须结束你的do块return:username是一个从一个动作中提取的纯值,因此只在do块中可见.IO在外界看到它之前,你需要把它抬起来.amount/ 也是如此tempamount.
而且为了完整起见:这背后有一些总体理论将它联系在一起.但是开始Haskell编程根本没有必要.我建议你做的是将大部分代码构造成纯粹的函数,这些函数可以折叠,控制和毁坏你的数据.然后构造一个薄的(尽可能薄的)IO前层,它与所述功能相互作用.你会惊讶于你需要多少IO!
1:它实际上有一个更通用的类型,但这与当下无关.