我试图在Int中读取然后在纯函数中使用读取值,但它似乎无法正常工作。在搜索了大量资源后,我使用了here。
所以我的代码如下:
main = do
putStrLn "Please input a number."
inputjar <- getLine
return (read inputjar :: Int)
哪种方法很好,但是当我想在我的纯函数中使用它时:
usrSetBrick :: [[Int]] -> [[Int]]
usrSetBrick xs = setBrick (main) (main) (main) xs
我收到编译错误:
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.
所以根据我的理解,main返回一个int。即便如此,正如我从中可以理解的那样 return(读取inputjar :: Int) 如何在我的函数中使读取输入可用?
答案 0 :(得分: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
但是,您的函数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
类型Int
和IO Int
在Haskell中不相同,您不能互换使用。这适用于[Int]
,Maybe Int
和Either 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
所有这些额外的回报在Haskell中都不起作用(至少在IO
monad中)。所有发生的事情都是将值包装在构造函数中并与该函数中的其余语句链接在一起。在Haskell社区中甚至有一些人认为return
既不必要又令人困惑。从技术上讲,return
相当于pure
的{{1}},所有Applicative
也是Monad
s,所以它并没有真正为我们提供任何东西。在遥远的未来的某个时刻,Applicative
函数可能会完全消失,完全被return
取代。同样,这些函数都不是Haskell语法的一部分,它们在核心库中被定义为普通的普通函数。