我有以下Haskell表达式:
a = getLine >>= putStrLn . filter isDigit >> a
我无法理解上述表达式的工作原理。我知道该>>=
函数需要一个monadic值和一个函数(该函数需要一个正常值并返回monadic值),然后返回monadic值。
我知道,getLine
并putStrLn
具有以下类型声明:
getLine :: IO String putStrLn :: String -> IO ()
所以下面的表达式部分:
a = getLine >>= putStrLn . filter isDigit
将返回一个IO ()
。但是,该函数>>
将获取第一个Monadic值和第二个Monadic值并返回第二个Monadic值。
给定原始表达式,传递给的第一个参数>>
将为type IO String
。第二个参数是a
。
我的问题是,的类型是什么a
,上述表达式如何工作以连续接收用户输入并仅将输入的数字部分打印回屏幕?任何见解都表示赞赏。
注意:我将a
函数重命名readPrintLoop
为@SamuelBarr所建议的名称,因为这样可以避免混淆。
我的问题是,的类型是什么
readPrintLoop
,上述表达式如何工作以连续接收用户输入并仅将输入的数字部分打印回屏幕?
readPrintLoop
具有类型:因此它是一个。该可以是任何类型的,因为我们从来没有“回报”是价值,我们将永远不会结束这个功能。readPrintLoop :: IO a
IO
a
该功能不断重复,因为它readPrintLoop
是根据自身定义的。readPrintLoop
定义为:
readPrintLoop :: IO a readPrintLoop = getLine >>= putStrLn . filter isDigit >> readPrintLoop
因此,我们这里具有无限递归,因为最终您将遇到a
,因此将其替换为另一个getLine >>= putStrLn . filter isDigit >> a
,依此类推。
但是,该函数
>>
将获取第一个Monadic值和第二个Monadic值并返回第二个Monadic值。
(>>)
等效于:
(>>) :: Monad m => m a -> m b -> m b u >> v = u >>= (\_ -> v)
因此,的实现a
等效于:
readPrintLoop :: IO a readPrintLoop = getLine >>= putStrLn . filter isDigit >>= \_ -> readPrintLoop
下划线变量_
将在此处传递()
。