Rob*_*art 2 monads haskell applicative
这里的两位非常简单的功能f和g.
{-# 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)
读取文件并*10在f写入应用性风格pure和(<*>).读取和*10输入的文件g是以monadic样式编写的>>=.(我一直在使用刻意避免liftM在g强调以下问题).
f和之间的语义差异是g什么?或者在这种情况下,它只是一种风格选择吗?
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在一起.