[英]Haskell: Understanding the bind and >> functions
我有以下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值。
给定原始表达式,传递给>>
的第一个参数将是IO String
类型。 第二个参数是a
。
我的问题是, a
的类型是什么,以及上述表达式如何继续用户输入并仅将输入的数字部分打印回屏幕? 任何见解都表示赞赏。
注意 :我按照readPrintLoop
建议将a
函数重readPrintLoop
为readPrintLoop ,因为这样可以避免一些混淆。
我的问题是,
readPrintLoop
的类型是readPrintLoop
,以及上述表达式如何工作以持续获取用户输入并仅将输入的数字部分打印回屏幕?
readPrintLoop
类型为: readPrintLoop :: IO a
所以它是一个IO
。 a
可以是任何类型,因为我们永远不会“返回”那个值,我们永远不会结束这个功能。
该函数不断重复,因为readPrintLoop
是根据自身定义的。 readPrintLoop
定义为:
readPrintLoop :: IO a
readPrintLoop = getLine >>= putStrLn . filter isDigit >> readPrintLoop
因此,我们在这里有无限递归,因为最终你会遇到a
,然后用另一个getLine >>= putStrLn . filter isDigit >> a
替换它getLine >>= putStrLn . filter isDigit >> 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
这里的下划线变量_
将被传递()
。
a = getLine >>= putStrLn . filter isDigit
不是 “表达的一部分”。
getLine >>= putStrLn . filter isDigit
是表达的一部分。 并且它不会“ 返回 IO ()
”。 它具有类型IO ()
(您已正确推断(*) )。 这是你所谈论的“一元价值” 。
给它一个名字, 任何名字 ,
ioAction :: IO ()
ioAction = getLine >>= (putStrLn . filter isDigit)
我们最终得到了
a = ioAction >> a
----------------------------------
(>>) :: IO a -> IO b -> IO b
ioAction :: IO ()
a :: IO b
----------------------------------
a :: IO b
以及所有的东西。
a
in的语义
a = ((>>) ioAction) a
由>>
的语义定义。
(*)
----------------------------------------------------
(>>=) :: m a -> (a -> m b) -> m b
getLine :: IO String m a
putStrLn :: String -> IO ()
putStrLn . filter isDigit :: String -> IO () a -> m b
---------------------------------------------------- ------------
getLine >>= (putStrLn . filter isDigit) :: IO () m b
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.