标签: pure-function

这个纯函数如何能够修改非私有状态?

TDPL,p.167:

只要函数中的可变状态完全是暂时的(即,在堆栈上分配)和私有(即,不通过引用可能污染它的函数传递),那么该函数可以被认为是纯的.

import std.stdio : writeln;

struct M{
  int[4] _data;

  pure ref int opIndex(size_t i){ return _data[i]; }
}

pure M foo(ref M m){

  m[0] = 1234;
  return m;
}

void main(){

  M m1 = M([7, 7, 7, 7]);

  writeln(m1);
  foo(m1);
  writeln(m1);
}

// output:
// M([7, 7, 7, 7])
// M([1234, 7, 7, 7])
Run Code Online (Sandbox Code Playgroud)

可变状态是暂时的,因为它在堆栈上,对吗?但它不是私密的.那怎么foo()允许修改m1

d pure-function

5
推荐指数
2
解决办法
269
查看次数

纯函数可以调用外部函数吗?

纯函数可以调用外部方法吗?

例如:

class Dog {
  function jump(name) {
    return "a dog named " + name + " jumped!"
  }

  function jumpTwice(names) {
    var result = [];
    for (var i = 0; i < 2; i++) {
       result.push(jump(names[i]));
    }
    return result.join("\n");
  }

}
Run Code Online (Sandbox Code Playgroud)

可以jumpTwice()算是一个pure function

functional-programming function concept pure-function

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

为什么React中的道具是只读的?

React文档说: React is pretty flexible but it has a single strict rule: all React components must act like pure functions with respect to their props.

这是为什么?

我猜想,如果您直接更改props的值,则组件不会重新渲染,这就是我们必须使用的原因setState。但我仍然不了解其背后的原因。为什么组件在其道具方面必须像纯函数一样?

pure-function reactjs

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

纯函数可以在同一个类中使用私有常量变量吗?

纯函数可以在同一个类中使用私有常量变量吗?

例如:

class TimesThousand {
  const CONSTANT = 1000;

  function calculate(number) {
    return number * CONSTANT;
  }
}
Run Code Online (Sandbox Code Playgroud)

可以calculate()被认为是一个pure function

functional-programming pure-function

3
推荐指数
1
解决办法
790
查看次数

您将如何编写一个从列表中删除元素的“纯”函数?

在 Java(或任何类似的语言)中,如何编写从列表中删除元素的纯函数(或方法)。

如果该元素在列表中,我们只需返回一个新的(理想情况下不可变的)列表,其中包含输入列表的所有元素,减去我们删除的元素。

但是如果在列表中找不到该元素,您将如何处理?

假设该方法接收 2 个参数,即listelement要删除的参数:

public SOMETHING remove(final List<String> list, final String element){
    // Copy the input list and remove the first occurrence of 'element', if I find it.
    // 
    // if I don't find it ... do something clever here ...
}
Run Code Online (Sandbox Code Playgroud)

如果我调用这个方法,并且element不包含在里面list

  • 抛出异常可能会使方法“不纯”(?)
  • 修改输入列表并返回布尔值(类似于List#remove())可能会使方法“不纯”(修改输入将是副作用)
  • 如果我调用此方法,将输入作为输出返回对我来说似乎不直观。
  • 返回Optional.of(listCopy)(编辑:发布后添加到我的问题中)
  • 还有其他想法吗?

编辑

我应该提到,我只想删除第一次出现的element,因此如果输入list多次出现element,我不想通过对我的remove() 方法的一次调用来删除它们(例如使用stream().filter())来删除它们。我刚刚编辑了代码示例中的注释来反映这一点。然而,这与我的问题并不完全相关,因为我的主要问题围绕如何使该方法直观易用并保持“纯粹”。

编辑2

我在上述建议的基础上添加了一个额外的想法。返回Optional.of(listCopy)似乎是迄今为止所提出的解决方案中最优雅的解决方案。它强制调用者检查请求的操作是否成功,并且(如果成功),它返回一个新列表,从而不会修改原始输入列表。如果操作不成功(element …

java functional-programming pure-function

3
推荐指数
1
解决办法
1081
查看次数

如何在纯函数中跳过不必要的IO?

更新

这个问题还有一个额外的限制,那就是IO尽可能避免。

这个限制最初是放在我的问题的最后,似乎很难被注意到。

我实际上知道如何在 Haskell 中实现我的目标,就像我知道如何在其他命令式编程语言中实现它一样 - 命令式方式。

但我没有使用任何其他命令式编程,对吗?我正在使用哈斯克尔。我想要一种 Haskell 方式,一种纯粹的方式。

我通过将额外限制重新定位在相对显眼的位置来重新组织我的问题。那是我的错。非常感谢这些快速回复。

原始问题

main :: IO ()
main =
    putStrLn =<< cachedOrFetched
        <$> getLine
        <*> getLine

cachedOrFetched :: String -> String -> String
cachedOrFetched cached fetched =
    if not $ null cached
    then cached
    else fetched
Run Code Online (Sandbox Code Playgroud)

上面的代码执行了两次IO。但期望的行为是当第一个 IO 的结果不为 null 时跳过第二个 IO。

我知道我可以通过使用door来实现这一点when。鉴于使用太多dos 违反了我使用 Haskell 的初衷,我可能会接受when.

或者,还有更好的方法?更纯粹的方式?

这是全部内容

大约两周前我开始学习 Haskell。我并不期待从中找到工作,只是被编程语言本身所吸引。因为据我所知这是“最纯粹的”。

起初,一切似乎都如我预期的那样好。但后来我发现我必须IO在我的纯代码中写 s 。我花了很长时间才找到一种控制不纯污染的方法。应用函子似乎是拯救者。

有了它,我可以将不纯的 IO“柯里化”到我的纯函数中,这样可以节省大量do,<- …

haskell functional-programming applicative pure-function

3
推荐指数
1
解决办法
203
查看次数

使用调试语句逃避安全性

我知道

debug writeln("Some good debug message")
Run Code Online (Sandbox Code Playgroud)

pure功能,但我已经仔细标记为@safe或的功能@trusted呢?DMD目前不允许使用debug writeln,因为writeln目前和类似@system.这是恕我直言,非常令人沮丧.有一个聪明的方式来逃避安全还是我暂时注释掉我所有的@safe@trusted标签?

d debug-print memory-safety pure-function

2
推荐指数
1
解决办法
140
查看次数

使用在读取后不会更改的参数

我正在学习Haskell并编写一个解决玩具问题的程序.在从文件读取参数之后,程序使用在运行时不会更改的参数k.我对使用纯函数非常陌生,我想尽可能多地编写纯函数.

我有一个数据类型Node,用于比较节点,获取节点的后代等等.目前,所有这些函数都将参数k作为参数,例如

compare k node1 node2 = ...
desc k node = ...
Run Code Online (Sandbox Code Playgroud)

每当我必须递归调用函数中的任何一个时,我必须重复k参数.这似乎是多余的,因为k对于这些函数永远不会有不同的值,因为它使类型签名的可读性降低,并且如果可能的话我想重构它.

是否有任何策略可以使用纯函数执行此操作,还是仅仅是我必须处理的限制?

我想到了什么

之前我在顶级硬编码k,它似乎工作(我能够在函数中使用k而不需要它作为显式参数).但是,一旦我需要从文件中读取输入,这显然是不可行的.

另一种可能的策略是在函数中定义所有这些main函数,但在Haskell中似乎强烈建议不要这样做.

monads haskell purely-functional pure-function

2
推荐指数
1
解决办法
116
查看次数

Powershell中的显式返回

我可以在javascript中编写以下代码:

function sum(num1, num2) {
  return num1 + num2;
}
Run Code Online (Sandbox Code Playgroud)

然后得到一个值

var someNum = sum(2,5);
Run Code Online (Sandbox Code Playgroud)

我想在Powershell中做同样的事情,但我阅读了以下指南:

PowerShell也知道return关键字; 然而,它遵循不同的逻辑.通常,返回的目的是结束代码段的执行并将控件返回给父块.

如果向return语句添加参数,则该值将确实返回到调用子例程.但是,这也适用于具有输出的所有其他语句.这意味着函数中产生的任何输出都将与返回参数一起存储在变量中.

我想为了拥有纯粹的功能而这样做.但是,它似乎正在做

var someNum = sum(2,5);

完全是多余的,当我可以调用上面的函数,定义someNum它的内部,它将在全局范围内可用.

我错过了什么或者是否有可能在Powershell中编写纯函数而不返回函数内部的所有内容?


有点切,但这是我的实际代码:

function GetPreviousKeyMD5Hashes() {
    $query = "SELECT Name, MD5, executed FROM [AMagicDb].[dbo].cr_Scripts";

    $command = New-Object System.Data.SQLClient.SQLCommand;
    $command.Connection = $connection;
    $command.CommandText = $query;

    try {
        $reader = $command.ExecuteReader();
        while ($reader.Read()) {
            $key = $reader.GetString(1)
            $previousScripts.Add($key) | Out-Null
        }

        $reader.Close();
        Write-Output "$(Get-Date) Finished querying previous scripts"
    }
    catch {
        $exceptionMessage = $_.Exception.Message;
        Write-Output …
Run Code Online (Sandbox Code Playgroud)

powershell pure-function

2
推荐指数
1
解决办法
128
查看次数

C++:有没有办法确保编译器调用两次相同的 const 方法给出相同的结果?

我对以下两个简单的片段感到困惑:

#include <vector>

struct A{
    int foo(int i) const {return v[i];}

    std::vector<int> v;
};

int f(const A &a, int i) {
    int j;
    j=a.foo(i);
    j=a.foo(i);
    return j;
}
Run Code Online (Sandbox Code Playgroud)

它给出了汇编代码:

movsxd  rax, esi
mov     rcx, qword ptr [rdi]
mov     eax, dword ptr [rcx + 4*rax]
ret
Run Code Online (Sandbox Code Playgroud)

movsxd  rax, esi
mov     rcx, qword ptr [rdi]
mov     eax, dword ptr [rcx + 4*rax]
ret
Run Code Online (Sandbox Code Playgroud)

这使:

push    rbp
push    rbx
push    rax
mov     ebp, esi
mov     rbx, rdi
call    _ZNK1A3fooEi
mov     rdi, rbx …
Run Code Online (Sandbox Code Playgroud)

c++ optimization assembly inline pure-function

2
推荐指数
1
解决办法
107
查看次数