例如,说putStrLn "one" >> putStrLn "two"
。如果我这样做:info >>
,我会看到:
type Monad :: (* -> *) -> Constraint
class Applicative m => Monad m where
...
(>>) :: m a -> m b -> m b
...
-- Defined in ‘GHC.Base’
infixl 1 >>
Run Code Online (Sandbox Code Playgroud)
我想看看表达式putStrLn "one" >> putStrLn "two"
是什么,替换>>
为这个定义。但不仅仅是这个函数表达式,任何函数表达式,如何查找和打印无糖版本。
(>>)
是一个函数,函数通常不被视为糖,即使它们来自类型类。但无论如何,在表达式中putStrLn "one" >> putStrLn "two"
,它来自IO
monad,所以它的定义将在instance Monad IO
. 它恰好是(*>)
which 本身thenIO
,这是这样的:
thenIO :: IO a -> IO b -> IO b
thenIO (IO m) k = IO (\ s -> case m s of (# new_s, _ #) -> unIO k new_s)
Run Code Online (Sandbox Code Playgroud)
请注意,这使用了IO
非公共 API 的部分,因此这并不是您可以在普通程序中自己编写的内容。