Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 适用于简单IO示例的应用程序与一元风格_Haskell_Monads_Applicative - Fatal编程技术网

Haskell 适用于简单IO示例的应用程序与一元风格

Haskell 适用于简单IO示例的应用程序与一元风格,haskell,monads,applicative,Haskell,Monads,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 <-

这里有两个非常简单的函数
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
{-#语言范围的TypeVariables}
模块测试在哪里
导入控制
f::IO()
f=do
y=返回。显示(*10) . 阅读)
写文件“out”y
f
中读取和
*10
的文件是以应用程序风格编写的,带有
pure
()
g
中读取和
*10
的文件是以一元格式编写的,带有
>=
。(我故意避免在
g
中使用
liftM
来强调下面的问题)

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

show。(*10) . read
是一个“非单子”函数,我的意思是,它在IO单子中不起任何作用,从它的类型可以看出

>>=返回。
可以缩短为

`liftM`
但是

应始终等同于

`fmap`
fmap
既不需要monad类型类也不需要applicative类型类,它只需要functor类型类

现在我们将注意力转向应用程序版本,如下所示:

(<*>) (pure ...
()(纯。。。
相当于
,它只是
fmap


因此,在这两种情况下,我们“实际上”只是在读写之间处理函子操作,尽管您以稍微不同的方式组合了函数(我们需要应用一个或多个“定律”将两个版本相互转换),语义是-或应该是-相同的。无论如何,它们肯定与IO单子相同。

是的,选择纯粹是风格上的,但两者都可以整理成更地道的:

应用程序函数最好以运算符形式编写,且无点:

f :: IO ()
f = show . (*10) . read <$> readFile "data" >>= writeFile "out"
f::IO()
f=显示。(*10)。读取读取文件“数据”>>=写入文件“输出”
在一元风格中,如果你更全心全意而不是毫无意义地避免操作员,它看起来更整洁:

g :: IO ()
g = do 
    y <- readFile "data" 
    let x = show . (*10) . read $ y
    writeFile "out" x
g::IO()
g=do

一元风格至少在我看来更具可读性:)你可以把
()(pure(show(*10)))(readFile“data”)
写成
show。(*10) . 读取读取文件“数据”
g :: IO ()
g = do 
    y <- readFile "data" 
    let x = show . (*10) . read $ y
    writeFile "out" x