bat*_*man 3 haskell functional-programming scala function
我正在阅读FP,我有两个基本问题:
FP表示功能应该采用一个输入并提供单个输出.那我该怎么做void方法呢?它没有任何回报吗?
FP说功能应该有单一的责任,那么我们如何处理log方法内的语句呢?那不违反规定吗?
希望知道他们如何在斯卡拉,哈斯克尔处理这些事情.提前致谢.
我假设您正在阅读一本名为"功能编程"的书,尽管它有助于了解作者是谁.在任何情况下,这些问题都相对容易回答,我会就Haskell给出答案,因为我不知道Scala.
那么我该如何处理void方法呢?它没有任何回报吗?
void像Haskell这样的纯函数语言中没有方法.纯函数没有副作用,所以没有返回值的纯函数是没有意义的,类似于
f :: Int -> ()
f x = let y = x * x + 3 in ()
Run Code Online (Sandbox Code Playgroud)
不会进行任何计算,y永远不会计算,你给出的所有输入都将返回相同的值.但是,如果您有一个不纯的函数,例如写入文件或将某些内容打印到屏幕上的函数,那么它必须存在于monadic上下文中.如果您还不了解monad,请不要担心.他们需要一点时间来习惯,但它们是一个非常强大和有用的抽象,可以使很多问题更容易.monad就像是IO,在Haskell中,它接受一个类型参数来指示可以存储在此上下文中的值.所以你可以有类似的东西
putStrLn :: String -> IO ()
Run Code Online (Sandbox Code Playgroud)
要么
-- FYI: FilePath is an alias for String
writeFile :: FilePath -> String -> IO ()
Run Code Online (Sandbox Code Playgroud)
这些都有副作用,由返回值表示IO something,而()某些东西意味着该操作没有有意义的结果.例如,在Python 3中,print函数返回,None因为在将值打印到屏幕后没有任何有意义的返回.的()也可以指一个monadic上下文具有有意义的值,如在readFile或getLine:
getLine :: IO String
readFile :: FilePath -> IO String
Run Code Online (Sandbox Code Playgroud)
在编写main函数时,您可以执行类似的操作
main = do
putStrLn "Enter a filename:"
fname <- getLine -- fname has type String
writeFile fname "This text will be in a file"
contents <- readFile fname
putStrLn "I wrote the following text to the file:"
putStrLn contents
Run Code Online (Sandbox Code Playgroud)
FP说函数应该有单一的resresponsibility,那么我们如何处理方法中的日志语句?那不违反规定吗?
大多数功能不需要在其中登录.我知道这听起来很奇怪,但这是真的.在Haskell和大多数其他函数式语言中,您将编写许多小的,易于测试的函数,每个函数都执行一步.在您的应用程序中有很多1或2行函数是很常见的.
当您确实需要进行日志记录时,假设您正在构建Web服务器,则可以采用几种不同的方法.实际上有一个调用的monad Writer可以让你在执行操作时聚合值.这些操作不一定是不纯的,做IO,它们可以完全是纯粹的.但是,可能用于Web服务器或大型应用程序的真正日志记录框架可能会带有自己的框架.这样您就可以设置日志记录到屏幕,文件,网络位置,电子邮件等.这个monad将包裹IOmonad,以便它可以执行这些副作用.更高级的可能会使用一些更高级的库,如monad变换器或可扩展的效果.这些让您可以将不同的monad"组合"在一起,这样您就可以同时使用两个实用程序.您可能会看到类似的代码
type MyApp a = LogT IO a
-- log :: Monad m => LogLevel -> String -> LogT m ()
getConnection :: Socket -> MyApp Connection
getConnection sock = do
log DEBUG "Waiting for next connection"
conn <- liftIO $ acceptConnection sock
log INFO $ "Accepted connection from IP: " ++ show (connectionIP conn)
return conn
Run Code Online (Sandbox Code Playgroud)
我不希望你完全理解这段代码,但我希望你能看到它将日志记录和网络操作混合在一起.该liftIO函数是monad变换器的常用函数,它将IO操作"转换"为包装IO的新monad.
这可能听起来很混乱,如果你已经习惯了Python,Java或C++这样的语言,那么它起初可能就是这样.我当然是!但是在我习惯以这种不同的方式思考问题后,我希望我一直都有这些OOP语言的结构.
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |