我承认我对功能编程知之甚少.我从这里和那里读到它,因此我们知道在函数式编程中,无论函数被调用多少次,函数都会为相同的输入返回相同的输出.它就像一个数学函数,对于函数表达式中涉及的输入参数的相同值,计算相同的输出.
例如,考虑一下:
f(x,y) = x*x + y; // It is a mathematical function
Run Code Online (Sandbox Code Playgroud)
无论你使用多少次f(10,4)
,它的价值永远都是104
.因此,无论您在何处编写f(10,4)
,都可以替换它104
,而无需更改整个表达式的值.此属性称为表达式的引用透明度.
正如维基百科所说(链接),
相反,在函数代码中,函数的输出值仅取决于输入到函数的参数,因此使用参数x的相同值调用函数f两次将产生相同的结果f(x).
函数式编程中是否存在时间函数(返回当前时间)?
如果是,那么它如何存在?它是否违反了函数式编程的原理?它特别违反了引用透明性,这是函数式编程的一个属性(如果我正确理解它).
或者如果不是,那么如何才能知道函数式编程中的当前时间?
这些术语似乎有 不同的定义,但我总是想到一个暗示另一个; 当表达式是引用透明但不纯粹时,我无法想到任何情况,反之亦然.
维基百科为这些概念维护单独的文章并说:
从参考透明度:
如果表达式中涉及的所有函数都是纯函数,则表达式是引用透明的.此外,如果丢弃它们的值并且它们的副作用无关紧要,则表达式中可以包含一些不纯的函数.
来自纯粹的表达:
构造纯表达式需要纯函数.[...]纯表达通常被称为引用透明.
我发现这些陈述令人困惑.如果副作用所谓的"非纯函数"是微不足道的,足以让不执行他们(即替换其这种函数的调用值没有实质性改变程序),它是一样的,如果它的是纯粹的第一名,不是吗?
有没有更简单的方法来理解纯表达式和引用透明的表达式之间的差异(如果有的话)?如果存在差异,则可以理解清楚地表明它的示例表达.
language-agnostic functional-programming side-effects referential-transparency purely-functional
我已经将IO monad描述为状态monad,状态是"现实世界".这种IO方法的支持者认为,这使IO操作变得纯粹,就像在引用透明时一样.这是为什么?从我的角度来看,IO monad中的代码似乎有很多可观察到的副作用.此外,是不是可以描述几乎任何非纯函数,如现实世界的功能?例如,我们不能想到,比方说,C的malloc是一个函数,它接受一个RealWorld和一个Int并返回一个指针和一个RealWorld,就像在Realmonorld隐含的IO monad中一样?
注意:我知道monad是什么以及它是如何使用的.请不要回复随机monad教程的链接,除非它专门解答我的问题.
Haskell通常被引用为纯函数式语言的示例.鉴于存在,这怎么可能是合理的System.IO.Unsafe.unsafePerformIO
?
编辑:我认为"纯功能"意味着不可能将不纯的代码引入程序的功能部分.
haskell type-systems functional-programming referential-transparency unsafe-perform-io
monad是一种数学结构,大量用于(纯)函数式编程,基本上是Haskell.然而,还有许多其他数学结构可用,例如应用函子,强单子或幺半群.有些更具体,有些更通用.然而,monads更受欢迎.这是为什么?
我提出的一个解释是,它们是通用性和特异性之间的最佳点.这意味着monad捕获关于数据的足够假设,以应用我们通常使用的算法以及我们通常满足monadic定律的数据.
另一种解释可能是Haskell为monad(do-notation)提供了语法,但没有为其他结构提供语法,这意味着Haskell程序员(以及函数式编程研究人员)直观地被用于monad,其中更通用或特定(高效)的函数将也工作.
我刚刚开始看看Haskell(我之前的FP体验是在Scheme中),我遇到了这段代码:
do { putStrLn "ABCDE" ; putStrLn "12345" }
Run Code Online (Sandbox Code Playgroud)
对我来说,这是程序式编程,如果有的话 - 特别是因为副作用的连续性.
有人请说明这段代码在任何方面都是"功能性的"吗?
这是对Haskell IO的合理看法吗?
给定程序时,Haskell运行时执行以下操作:
main
返回"IO计算"这种两阶段方法允许main
保持纯粹的功能.
在这种情况下,IO计算就像是具有显式排序的Haskell的特殊版本 - 或者可能有更好的方法来描述它?
此代码(取自Learn You A Haskell):
main = do putStr "Hey, "
putStr "I'm "
putStrLn "Andy!"
Run Code Online (Sandbox Code Playgroud)
显然是个傻瓜
main = putStr "Hey, " >>=
(\_ -> putStr "I'm " >>=
(\_ -> putStrLn "Andy!"))
Run Code Online (Sandbox Code Playgroud)
其中,正如我所理解的那样可以解释为"为了放入斯特伦"安迪!"我首先要把putStr"我是",为了做到这一点,我首先要把putStr"嘿,";
我不同意这种解释,这很烦人,因为编译器显然不会让我感到困惑.我遇到的问题是,lambdas忽略了他们的论点,在懒惰的评估期间,这种事情是不是应该被识别和短路?
此外,当然,绑定会返回IO操作,当IO操作进入main时,它会被执行.但是什么阻止它打印"嘿,安迪!我是"?我怀疑这是绑定正在做什么.
此外,类型"IO()"的IO操作如何携带足够的信息以允许运行时系统打印"嘿,我是安迪!"?IO()与IO()的不同之处在于打印"Hello World!" 或写入文件?
考虑另一个,来自monad的维基百科页面:
加糖版:
do
putStrLn "What is your name?"
name <- getLine
putStrLn ("Nice to meet you, " ++ name ++ "!")
Run Code Online (Sandbox Code Playgroud)
Desugared版本:
putStrLn "What is your name?" >>=
(\_ ->
getLine >>=
(\name ->
putStrLn ("Nice to meet you, " …
Run Code Online (Sandbox Code Playgroud) 鉴于以下计划,我遇到了与monad打交道的问题.
module Main
where
import System.Environment
import System.Directory
import System.IO
import Text.CSV
--------------------------------------------------
exister :: String -> IO Bool
exister path = do
fileexist <- doesFileExist path
direxist <- doesDirectoryExist path
return (fileexist || direxist )
--------------------------------------------------
slurp :: String -> IO String
slurp path = do
withFile path ReadMode (\handle -> do
contents <- hGetContents handle
last contents `seq` return contents )
--------------------------------------------------
main :: IO ()
main = do
[csv_filename] <- getArgs
putStrLn (show csv_filename)
csv_raw <- slurp …
Run Code Online (Sandbox Code Playgroud) 我的问题是haskell中的monad是否真的保持了hakell的纯度,如果是的话.我经常读到副作用是如何不纯的,但有用的程序(例如i/o)需要副作用.在下一句中,声明haskell的解决方案是monads.然后monad在某种程度上被解释,但实际上并不是他们如何解决副作用问题.
我已经看到了这个和这个,我对答案的解释实际上就是我自己读到的那个 - IO monad的"动作"不是i/o本身,而是执行时执行的对象/ O.但是我发现可以为任何代码或任何已编译的可执行文件创建相同的参数.难道你不能说C++程序只在编译代码执行时产生副作用吗?所有的C++都在IO monad中,所以C++是纯粹的?我怀疑这是真的,但我老实说不知道它不是以什么方式存在.事实上,Moggi(sp?)最初是否使用monads来模拟命令式程序的指称语义?
一些背景:我是haskell和函数式编程的粉丝,我希望随着我的学习继续学习更多.例如,我理解参考透明度的好处.这个问题的动机是我是一名研究生,我将为编程语言课提供2个1小时的演示文稿,其中一个特别涉及haskell,另一个涉及函数式编程.我怀疑大多数班级不熟悉函数式编程,可能已经看过一些方案.我希望能够(合理地)清楚地解释monad如何解决纯度问题而不进入类别理论和monad的理论基础,我没有时间去讨论,无论如何我不完全了解自己 - 当然还不够好.
我想知道在这种情况下"纯度"是不是真的很明确?