gpt4 book ai didi

Haskell 输入返回元组

转载 作者:行者123 更新时间:2023-12-04 22:01:28 26 4
gpt4 key购买 nike

我想知道 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)

请帮忙。

谢谢。

最佳答案

Haskell 中的 IO 不像您习惯的语言中的 IO 那样工作。 Haskell 中的所有函数都必须是纯函数:也就是说,如果使用参数 f 调用函数 x ,则调用它一次、两次或一百次没有区别。不过,请考虑一下这对 IO 意味着什么。天真地,getLine 的类型应该是 getLine :: String ,或者可能是 getLine :: () -> String 。 ( () 是单元类型,其唯一值是 () ;它有点像类 C 语言中的 void 类型,但它只有一个值。)但这意味着每次编写 getLine 时,它​​都会必须返回相同的字符串,这不是您想要的。这就是 IO 类型的目的:封装 Action 。这些 Action 与功能不同。它们代表不纯的计算(尽管它们本身是纯的)。 IO a 类型的值表示一个操作,该操作在执行时返回 a 类型的值。因此, getLine 的类型为 getLine :: IO String :每次评估 Action 时,都会生成一个 String(通过从用户那里读取)。类似地, putStr 的类型为 putStr :: String -> IO () ;它是一个接受字符串并返回一个 Action 的函数,该 Action 在运行时不返回任何有用的信息……但是,作为副作用,它会在屏幕上打印一些内容。

您正在尝试编写 IO () -> ([Char], Int) 类型的函数。这将是一个将操作作为输入并返回一个元组的函数,这不是您想要的。你需要一个 IO (String, Int) ——一个 Action ,它在运行时产生一个由字符串(它是 [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)

请注意,我只做了两个更改(并删除了一个空行)。首先,我改变了函数的类型,就像我上面说的那样。其次,我将 show 更改为 readshow 函数具有 Show a => a -> String 类型:它是一个函数,它接受任何可以显示的内容并生成一个表示它的字符串。你想要 read ,它的类型是 Read a => String -> a :给定一个字符串,它解析它并返回一些可读的值。

你问的另一件事是返回一个元组 (String, Int) 而不是 Action IO (String, Int) 。没有纯粹的方法可以做到这一点。换句话说,没有纯函数 IO a -> a 。为什么是这样?因为 IO a 代表一个不纯的 Action ,它取决于现实世界。如果我们有这样的函数 impossibleRunIO :: IO a -> a ,那么我们希望它是 impossibleRunIO getLine == impossibleRunIO getLine 的情况,因为该函数必须是纯函数。但这没有用,因为我们希望 impossibleRunIO 能够真正与现实世界交互!因此,这个纯函数是不可能的。进入 IO 的所有东西永远不会离开。这就是 return 的作用:它是一个函数,在这种情况下 1,类型为 return :: a -> IO a ,它使您能够将纯值放入 IO 中。对于任何 xreturn x 是一个 Action ,在运行时,它总是产生 x 。这就是为什么您必须以 do 结束 return 块的原因: username 是您从 Action 中提取的纯值,因此仅在 do 块中可见。你需要把它提升到 IO 才能让外界看到它。 amount/ tempamount 也是如此。

并且只是为了完整起见:这背后有一些总体理论将它联系在一起。但是对于开始 Haskell 编程根本没有必要。我建议做的是将大部分代码构建为折叠、旋转和破坏数据的纯函数。然后构建一个薄的(尽可能薄的) IO 前层,它与所述函数交互。您会惊讶于您需要的 IO 如此之少!

1:实际上,它具有更通用的类型,但是暂时不相关。

关于Haskell 输入返回元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3066956/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com