如何在Int中读取并在另一个函数中使用它

use*_*707 0 io parsing haskell

我试图在Int中读取然后在纯函数中使用读取值,但它似乎无法正常工作.在搜索了大量资源后,我使用了从这里开始.

所以我的代码如下:

main = do
putStrLn "Please input a number."
inputjar <- getLine
return (read inputjar :: Int)
Run Code Online (Sandbox Code Playgroud)

哪个工作正常,但当我想在我的纯函数中使用它时:

usrSetBrick :: [[Int]] -> [[Int]]
usrSetBrick xs = setBrick (main) (main) (main) xs
Run Code Online (Sandbox Code Playgroud)

我收到编译错误:

Couldn't match expected type `Int' with actual type `IO Int'
In the first argument of `setBrick', namely `(main)'
In the expression: setBrick (main) (main) (main) xs
In an equation for `usrSetBrick':
usrSetBrick xs = setBrick (tull) (tull) (tull) xs
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

所以根据我的理解,main返回一个int.即使它应该,因为我可以从
return中理解(读取inputjar :: Int)如何使读取输入在我的函数中可用?

bhe*_*ilr 6

你可能不想用它main来返回东西,因为它是你程序的入口点.相反,你可以编写一个函数

getInt :: IO Int
getInt = do
    input <- getLine
    return (read input)  -- Don't have to specify Int here, GHC can figure it out from the type signature
Run Code Online (Sandbox Code Playgroud)

但是,您的功能setBrick(可能是该类型Int -> Int -> Int -> [[Int]] -> [[Int]])无法getInt直接使用.这是设计的,Haskell的类型系统强迫您将IO操作与纯函数分开处理(一旦习惯了它,它就是推理代码的绝佳工具).相反,你可以做类似的事情

promptInt :: IO Int
promptInt = do
    putStrLn "Please input a number."
    getInt

usrSetBrick :: [[Int]] -> IO [[Int]]
usrSetBrick xs = do
    a <- promptInt
    b <- promptInt
    c <- promptInt
    return $ setBrick a b c xs
Run Code Online (Sandbox Code Playgroud)

Haskell中的类型IntIO Int不一样,你不能互换使用.这适用于类型,如真[Int],Maybe IntEither String Int为好,这些都不一样Int.既然main是一个IO函数,它不返回Int,它返回IO Int.实际上,return根本不是Haskell中的特殊构造,它只是一个正常的函数,恰好将一个值包装在一个Monad.在这种情况下,Monad使用存在是IO,使return (read inputjar :: Int)具有类型IO Int.


为了扩展@ Zeta在下面的评论,Haskell return并不特别,更重要的是不提前退出函数.以下代码将演示如下:

doSomething :: IO Int
doSomething = do
    return "Test"  -- Wouldn't type-check if this exited early
    return 123     -- Would type check, but is ignored
    putStrLn "You'll see this line printed"
    return ()      -- Doesn't affect anything
    x <- getLine   -- Still happens
    return 5678
    putStrLn "Your input is meaningless!  Here's a 0"
    return ([1, 2], "hello", "world")
    return 0       -- This is the actual return value
Run Code Online (Sandbox Code Playgroud)

所有这些额外的回报在Haskell中都没有任何作用(至少在IOmonad中).所有发生的事情都是将值包装在构造函数中并与该函数中的其余语句链接在一起.在Haskell社区中甚至有一些人认为return既不必要又令人困惑.从技术上讲,return相当于pureApplicativeS,和所有的Monads为也ApplicativeS,SO它不是真正的为我们提供什么.在遥远的未来某个时刻,这个return功能可能会完全消失,被完全取代pure.同样,这些函数都不是Haskell语法的一部分,它们在核心库中被定义为普通的普通函数.