理解Haskell中的$

mdm*_*mdm 2 monads haskell monad-transformers

我在理解以下代码时遇到了一些困难(在IO顶层的ErrorT monad中执行):

closePort [Port port] = liftIO $ hClose port >> (return $ Bool True)
Run Code Online (Sandbox Code Playgroud)

>>有更高的优先权$.所以Bool True第一个包裹在IO比提升与liftIOhClose先解除?在其它字>>return在IO单子或ErrorT单子执行?

ham*_*mar 14

在这种情况下,您不必担心优先级,因为

liftIO (hClose port >> return (Bool True))
Run Code Online (Sandbox Code Playgroud)

liftIO (hClose port) >> return (Bool True)
Run Code Online (Sandbox Code Playgroud)

由于monad变压器定律,它必须是等价的

  1. 提升return没有任何作用.

    lift . return = return
    
    Run Code Online (Sandbox Code Playgroud)
  2. 提升两个动作的顺序与单独提升它们相同.

    lift (m >>= f) = lift m >>= (lift . f)
    
    Run Code Online (Sandbox Code Playgroud)

liftIO 也应该遵循这些法律,所以我们可以看到

liftIO (hClose port >> return (Bool True))
= -- definition of >>
liftIO (hClose port >>= \_ -> return (Bool True))
= -- second monad transformer law
liftIO (hClose port) >>= \_ -> liftIO (return (Bool True))
= -- first monad transformer law
liftIO (hClose port) >>= \_ -> return (Bool True)
= -- definition of >>
liftIO (hClose port) >> return (Bool True)
Run Code Online (Sandbox Code Playgroud)


Dan*_*her 7

给定的代码相当于

closePort [Port port] = liftIO ( hClose port >> (return ( Bool True) ) )
Run Code Online (Sandbox Code Playgroud)

所以整个(hClose port) >> (return (Bool True))是争论的liftIO.所以,(>>)并且return是那些IO,然后整个IO计算被提升liftIO.