标签: referential-transparency

了解参考透明度

一般来说,我很头疼因为我的推理出了问题:

  1. 对于1组参数,参照透明函数将始终返回1组输出值.

  2. 这意味着这样的函数可以表示为真值表(一组表为1组参数指定了一组输出参数).

  3. 这使得这些功能背后的逻辑组合的(而不是顺序的)

  4. 这意味着使用纯函数语言(只有rt函数),可以只描述组合逻辑.

最后一个陈述来自这个推理,它显然是错误的; 这意味着推理有误.[问题:这个推理在哪里出错?]

UPD2.你们这些人说的很多有趣的东西,但没有回答我的问题.我现在更明确地定义它.对不起弄乱问题定义!

functional-programming referential-transparency

7
推荐指数
2
解决办法
570
查看次数

是否存在双向多图持久数据结构?

换句话说,我们可以有效地在持久数据结构中建模多对多关系吗?


建议使用一对单向多图.但是,我不确定这对于在持久数据结构中删除是否会很好.让我们假设我们将键1..4设置为值"1".."4"并且假设它们各自引用所有其他的,所以我们有两个看起来非常相似的两个方向的地图:

{1 => ["2","3","4"],2 => ["1","3","4"],...} {"1"=> [2,3, 4],"2"=> [1,3,4],...}

现在我们想要从系统中完全删除第1项.这需要更改第一个映射中的一个节点,但它需要在第二个映射中更改n-1个节点.对于成千上万的n(可能在我考虑这个的情况下)不会那么贵吗?或者是针对处理此类更改而优化的多图?这是一个病态案例,但仍然......


四叉树似乎是一个迷人的想法.我要多考虑一下.

persistence functional-programming immutability referential-transparency data-structures

7
推荐指数
2
解决办法
1339
查看次数

如何通过隐藏"状态"更改来在类型sig中编写没有IO的haskell函数

我在haskell中编写了一个函数,它接受一些参数,如Word32,String(忽略currying)并输出IO Word32.现在,这是一个真正意义上的函数:对于相同的输入,输出将始终相同.没有副作用.函数返回IO Word32而不是Word32的原因是该函数在循环中多次更新许多32位线性反馈移位寄存器(lfsr)和其他寄存器,以便计算最终的Word32输出.

我的问题是:鉴于此函数实际上没有副作用,是否可以在函数实现中隐藏这些寄存器更新,以便该函数返回Word32而不是IO Word32?如果是这样,怎么样?

monads haskell functional-programming referential-transparency unsafe-perform-io

7
推荐指数
2
解决办法
725
查看次数

如果你编译一个没有输入的程序会怎么样?(Haskell IO纯度问题(再次))

putStrLn当使用任何参数调用时,将始终返回type的值IO ().我同意这是纯粹的,我可以处理.但它是否具有参考透明度?我是这么认为的,因为对于任何给定的输入,你可以用一个IO ()将在stdout抛出正确字符串的函数调用替换.

所以我很酷putStrLn,但是getLine当没有参数调用时可以返回任何数量的东西,只要它们是类型的IO String.这既不是纯粹的,也不是引用透明的吗?

愚蠢的迂腐问题,它可能不会改变我编写代码的方式,但我真的想要一劳永逸地解决这个问题.(我知道IO monad会正确排序,这不是我的问题)

这为我提出了另一个问题.编译器是否足够智能以识别不带输入的程序?比如说我编译

main = putStrLn . show $ map (+1) [1..10]
Run Code Online (Sandbox Code Playgroud)

GHC是否足够聪明,可以将该程序减少到IO ()导致[2,3,4,5,6,7,8,9,10,11]打印出来的程序?或者它仍在运行并在运行时评估/执行所有内容?对于不需要输入的任意程序也是如此.GHC是否采用了这样一个事实:整个程序是透明的,并且可以简单地用它的价值取代?

haskell functional-programming side-effects referential-transparency

7
推荐指数
3
解决办法
693
查看次数

移动语义对于 Rust 中的引用透明性意味着什么?

我正在尝试弄清楚移动语义如何影响引用透明度。

引用透明(RT) 允许我们在不改变程序含义的情况下用其结果替换任何表达式(从Scala 中的函数式编程转述)。例如,我可以用 替换1 + 1我程序中的任何地方2,并且什么都不应该改变。这个 Python 程序是引用透明的:

@dataclass
class Bucket:
    things: List[str]

leaves = ["leaves"]

def bucket_with_sand(things: List[str]) -> Bucket:
    return Bucket(things + ["sand"])

bucket_with_sand(leaves)  # can be replaced with Bucket(["leaves", "sand"]) with no change to the program
Run Code Online (Sandbox Code Playgroud)

而这个函数就地改变了它的参数

def bucket_with_sand(things: List[str]) -> Bucket:
    things += ["sand"]
    return Bucket(things)
Run Code Online (Sandbox Code Playgroud)

因此用其结果替换函数调用会改变含义。它不再具有引用透明性。在像 Rust 那样具有移动语义的语言中,我们可以通过移动leaves(并依赖于VecCopy)来避免这个问题:

struct Bucket {
    things: Vec<&str>,
}

let leaves = …
Run Code Online (Sandbox Code Playgroud)

functional-programming referential-transparency move-semantics rust

7
推荐指数
1
解决办法
354
查看次数

为什么懒惰与参考透明度相吻合?

我正在阅读Haskell教程(Learn You a Haskell),其中作者说懒惰与参考透明度相得益彰.经过更多的阅读和一些搜索,我仍然不明白为什么.请注意,我确实理解参考透明度和懒惰的优点,但是它们在一起令我感到不安.

这两者结合有什么特别的好处吗?

或者也许作者只是想说他们都很高兴并且表达得那么含糊不清?

haskell referential-transparency lazy-evaluation

6
推荐指数
2
解决办法
579
查看次数

参考透明度

当在函数式编程中使用术语"引用透明"时,术语"不可观察"的含义是什么?

functional-programming scala referential-transparency

6
推荐指数
1
解决办法
2322
查看次数

使用参照透明度来预先计算haskell中的值

假设我们有一个这样的程序:

list = [1..10000000]

main = print $ sum list
Run Code Online (Sandbox Code Playgroud)

我想要编译这样,可执行文件只打印50000005000000,而不需要花费太多时间和精力.

基本上,任何可以确定计算的表达式(也许严格性分析可以在这里帮助)都可以在编译期间预先计算(即我们使用参考透明度来表示在计算值时它并不重要).

简而言之:"必须计算"+参考 - 透明度=可以预先计算

这就像运行程序,直到我们点击依赖于输入的东西(即程序的核心,在所有输入中共同的,将被预先计算)

是否存在当前实现此目的的机制(使用Haskell或任何其他语言)?[请不要指向C++中的模板之类的东西,因为它首先没有引用透明度.]

如果没有,这个问题有多难?[伴随的技术(和理论)问题是什么?]

haskell referential-transparency precompute

6
推荐指数
2
解决办法
412
查看次数

为什么延迟工厂方法在F的上下文中具有返回值

我看cats.effect.concurrent.Deferred,发现所有纯正它的同伴对象中的工厂方法返回的F[Deferred[F, A]],不只是Deferred[F, A]

def apply[F[_], A](implicit F: Concurrent[F]): F[Deferred[F, A]] =
  F.delay(unsafe[F, A])
Run Code Online (Sandbox Code Playgroud)

  /**
    * Like `apply` but returns the newly allocated promise directly instead of wrapping it in `F.delay`.
    * This method is considered unsafe because it is not referentially transparent -- it allocates
    * mutable state.
    */
  def unsafe[F[_]: Concurrent, A]: Deferred[F, A]
Run Code Online (Sandbox Code Playgroud)

为什么?

abstract class具有限定(文档略)两种方法:

abstract class Deferred[F[_], A] {
  def get: F[A]
  def complete(a: A): …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala referential-transparency cats-effect

6
推荐指数
1
解决办法
92
查看次数

例外和参考透明度

阅读"Scala中的函数式编程",我对有关异常不是引用透明的部分感到有些困惑.

给出的例子是

def failingFn(i: Int): Int = {
  val y: Int = throw new Exception("fail!")
  try {
    val x = 42 + 5
    x + y
  }
  catch { case e: Exception => 43 }
}
Run Code Online (Sandbox Code Playgroud)

因此,本书中给出的论点y是不是引用透明的,因为如果我们将它替换为try块中的主体,我们得到的结果与直接运行函数时的结果不同.这对我没有任何意义,因为整个函数从一开始就是非终止的,那么说函数体中的值是不是在引用上是透明的呢?我心中的天真替代如下

def failingFn(i: Int): Int = {
  val y: Int = throw new Exception("fail!")
  try {
    val x = 42 + 5
    x + ((throw new Exception("fail!")): Int)
  }
  catch { case e: Exception => 43 }
}
Run Code Online (Sandbox Code Playgroud)

并且仍然以相同的异常失败.

此外, …

functional-programming scala referential-transparency

5
推荐指数
1
解决办法
1188
查看次数