适用于简单IO示例的适用于monadic风格

Rob*_*art 2 monads haskell applicative

这里的两位非常简单的功能fg.

{-# LANGUAGE ScopedTypeVariables #-}

module Test where

import Control.Applicative

f :: IO ()
f = do
    y <- (<*>) (pure (show . (*10))) (read <$> readFile "data")
    writeFile "out" y

g :: IO ()
g = do
    y <- (readFile "data" >>= return . show . (*10) . read)
    writeFile "out" y
Run Code Online (Sandbox Code Playgroud)

读取文件并*10f写入应用性风格pure(<*>).读取和*10输入的文件g是以monadic样式编写的>>=.(我一直在使用刻意避免liftMg强调以下问题).

f和之间的语义差异是g什么?或者在这种情况下,它只是一种风格选择吗?

Rob*_*een 8

show . (*10) . read 是一个"非monadic"函数 - 我的意思是,它在IO monad中没有做任何事情,正如你可以从它的类型中看到的那样.

>>= return . 可以缩短为

`liftM`
Run Code Online (Sandbox Code Playgroud)

`liftM`
Run Code Online (Sandbox Code Playgroud)

应始终相当于

`fmap`
Run Code Online (Sandbox Code Playgroud)

fmap 既不需要monad类型类也不需要应用类型类,它只需要仿函数类型类.

现在把注意力转向应用版本,这个:

(<*>) (pure ...
Run Code Online (Sandbox Code Playgroud)

相当于<$>,这只是fmap.

因此,在这两种情况下,我们"真的"只是在函数中使用函数操作,在阅读和写作之间,虽然你以稍微不同的方式组合了函数(我们需要应用一个或多个"法则"来翻译这两个函数)相互之间的版本),语义是 - 或应该 - 相同.无论如何,当然他们和IO monad在一起.