标签: referential-transparency

Haskell中随机数的采样序列

我需要用于模拟的小型高斯随机数列表,所以我尝试了以下方法:

import System.Random

seed = 10101
gen = mkStdGen seed

boxMuller mu sigma (r1,r2) =  mu + sigma * sqrt (-2 * log r1) * cos (2 * pi * r2) 
Run Code Online (Sandbox Code Playgroud)

这只是Box-Muller算法 - 给定r1,r2在[0,1]区间内的均匀随机数,它返回一个高斯随机数.

normals 0 g = [] 
normals n g = take n $ map (boxMuller 0 1) $ pairs $ randoms g
    where pairs (x:y:zs) = (x,y):(pairs zs)
Run Code Online (Sandbox Code Playgroud)

所以我normals每次需要我的随机数列表时都会使用这个函数.

问题必须明显:它始终生成相同的序列,因为我总是使用相同的种子!我没有得到新的序列,我只是一直得到序列的前n个值.

我明确假装的是,当我输入时:

x = normal 10 
y = normal 50
Run Code Online (Sandbox Code Playgroud)

我要将x作为前10个值,将map (boxMuller 0 1) $ …

random haskell functional-programming referential-transparency

18
推荐指数
2
解决办法
3941
查看次数

如何捕获(并忽略)对错误函数的调用?

我很惊讶我无法在任何地方找到答案.

我正在编写一个roguelike,我正在使用来自hackage的ncurses库,这是ncurses库的一个非常好的包装器.现在ncurses有这个怪癖,如果你试图写下右下角,它会这样做,然后它会尝试将光标移动到下一个角色,然后失败,因为没有地方可以将它移动到.它返回一个您只能忽略的错误值.

我的问题是haskell ncurses库编写者尽职地检查所有调用的任何错误,当有一个时,他调用:error"drawText:etc etc.".

在其他语言中,比如c或python,为了解决这个问题,你不得不忽略错误或捕获并忽略异常,但对于我的生活,我无法弄清楚如何在haskell中做到这一点.错误功能是不可恢复的吗?

我将在本地修改库,以便在必要时不检查该函数的错误,但我讨厌这样做.我也对任何可以让我在不移动光标的情况下绘制最后一个字符的解决方法持开放态度,但我不认为这是可能的.

haskell exception-handling exception referential-transparency

17
推荐指数
2
解决办法
4290
查看次数

Haskell中函数调用的优化

不知道谷歌究竟要解决这个问题,所以我会直接发布到SO:

  1. Haskell中的变量是不可变的
  2. 纯函数应该为相同的参数产生相同的值

从这两点可以推断,如果你somePureFunc somevar1 somevar2在代码中调用两次,那么在第一次调用期间计算值是有意义的.结果值可以存储在某种巨型哈希表(或类似的东西)中,并在后续调用函数时查找.我有两个问题:

  1. GHC实际上是否进行了这种优化?
  2. 如果确实如此,那么重复计算实际上比查找结果更便宜的情况是什么?

谢谢.

optimization haskell memoization referential-transparency ghc

17
推荐指数
2
解决办法
631
查看次数

参考透明度与Haskell中的多态性

说我有一个功能:

f :: Int -> (Rational, Integer)
f b = ((toRational b)+1,(toInteger b)+1)
Run Code Online (Sandbox Code Playgroud)

我想像这样抽象出(+1):

f :: Int -> (Rational, Integer)
f b = (h (toRational b)
      ,h (toInteger b))
    where h = (+1)
Run Code Online (Sandbox Code Playgroud)

这显然不会起作用,但如果我指定类型签名,它将起作用:

f :: Int -> (Rational, Integer)
f b = (h (toRational b)
      ,h (toInteger b))
    where h :: Num a => a -> a
          h = (+1)
Run Code Online (Sandbox Code Playgroud)

假设我现在想通过传递h作为参数来进一步抽象函数:

f :: Num a => Int -> (a -> a) -> (Rational, Integer)
f b g = (h …
Run Code Online (Sandbox Code Playgroud)

polymorphism haskell referential-transparency higher-rank-types

17
推荐指数
1
解决办法
384
查看次数

在haskell计算中"注入"进度记录/跟踪?

我正在挑选一个特定的任务来说明我在说什么

假设我想通过检查下面的每个数字(如果它是一个因子,然后将它们加在一起)来天真地找到大数的所有因子的总和.

在命令式编程语言中,IO和纯计算之间没有分离,你可能会做这样的事情

def sum_of_factors(n):
  sum = 0
  for i between 1 and n:
    if (n % i == 0):
      sum += i
  return sum
Run Code Online (Sandbox Code Playgroud)

但是如果我n很大,我最终会在计算完成之前长时间盯着空屏幕.所以我添加一些日志记录 -

def sum_of_factors(n):
  sum = 0
  for i between 1 and n:
    if (i % 1000 == 0):
      print "checking $i..."
    if (n % i == 0):
      print "found factor $i"
      sum += 1
  return sum
Run Code Online (Sandbox Code Playgroud)

实际上,这个增加是微不足道的.

现在,如果我要在教科书中使用haskell,我可能会这样做

sum_of_factors :: Int -> Int
sum_of_factors n = foldl' (+) 0 factors
  where
    factors …
Run Code Online (Sandbox Code Playgroud)

haskell referential-transparency

15
推荐指数
2
解决办法
580
查看次数

怎么称OOP相当于"参考透明度"?

我的理解是," 引用透明度 " 这个术语实际上只能应用于功能代码.但是,对面向对象代码中的对象的方法调用可以具有类似的属性,即方法的返回值和方法调用后的对象的状态仅取决于调用之前的对象的状态,以及方法的论点.

即功能参照透明度:

i = foo(n, m);
// return value depends only on n, m
Run Code Online (Sandbox Code Playgroud)

OO"参考透明度":

i = obj.foo(n, m);
// return value, and subsequent state of obj, depends 
// only on initial state of obj, n, m
Run Code Online (Sandbox Code Playgroud)

这个房产有名字吗?

如果obj在调用期间状态没有改变foo(),则"面向对象"样式等同于函数形式,如果支持函数重载,则可以将其重写为:

i = foo(obj, n, m);
// return value depends only on obj, n, m
Run Code Online (Sandbox Code Playgroud)

但是,obj在方法调用中更改状态是很常见的,所以我不确定这是否有助于分析...

oop functional-programming referential-transparency

12
推荐指数
1
解决办法
849
查看次数

返回打破引用透明度?

我正在阅读Scala WartRemover工具的描述,并对其中的一个要点感到困惑.描述说:

return打破参考透明度.重构以安全的方式终止计算.

// Won't compile: return is disabled
def foo(n:Int): Int = return n + 1
def foo(ns: List[Int]): Any = ns.map(n => return n + 1)
Run Code Online (Sandbox Code Playgroud)

这对我来说没有任何意义,两个例子看起来都是透明的.是否有某种方式使return关键字使函数更有可能破坏引用透明度?我只是完全误解了他们的观点?

functional-programming scala referential-transparency

12
推荐指数
1
解决办法
358
查看次数

使用函数编程语言处理具有内部状态的外部库的最优雅方法是什么?

我目前正在玩Scala开发,但我需要与诸如box2d之类的库集成来处理物理.问题是,这需要依赖于管理其自身状态的外部库.您可以跟踪传递到box2d世界的物体.总结一下有用的方面:

  • Box2d管理世界中的状态,并在每个滴答/步骤后修改它们
  • 您创建(使用FP)传递到此世界的实体
  • Box2d在内部修改这些实体的状态
  • 要跟踪对象,请保持对它们的引用
  • 您很可能希望使用正文中的信息来呈现您的代码,因此我认为跟踪该信息的唯一方法是跟踪可变集合中的所有引用.它需要在所有帧中存活.

所以我的问题是:

如何以优雅的方式跟踪这些引用(用于函数式编程),以及如何在代码的其余部分中最小化它对纯度的影响?

像国家单子这样的东西在这里我不会帮助我

haskell functional-programming scala referential-transparency

11
推荐指数
1
解决办法
638
查看次数

使用Haskell查找网格上两点之间的最短路径

这是一个我可以很容易地以非功能性方式解决的问题.

但是在Haskell中解决这个问题给了我很大的麻烦.在功能编程方面,我缺乏经验肯定是一个原因.

问题:

我有一个2D字段分为相同大小的矩形.一个简单的网格.一些矩形是空的空间(并且可以通过),而其他矩形是无法通过的.给定起始矩形A和目标矩形B,我如何计算两者之间的最短路径?只能垂直和水平移动,步骤单个矩形大.

我将如何在Haskell中完成此任务?代码片段肯定是受欢迎的,但肯定不是必要的.并且非常欢迎链接到更多资源!

谢谢!

algorithm haskell referential-transparency shortest-path

10
推荐指数
1
解决办法
2749
查看次数

如何在Data.Set中插入O(log(n))?

在查看文档时Data.Set,我看到在树插入元素被称为O(log(n)).但是,我会直观地期望它是O(n*log(n))(或者可能是O(n)?),因为参照透明度需要在O(n)中创建前一个树的完整副本.

据我所知,例如(:)可以将O(1)代替O(n),因为这里不必复制完整列表; 新的列表可以由编译器优化为第一个元素加上指向旧列表的指针(请注意,这是一个编译器 - 而不是语言级别 - 优化).但是,在a中插入一个值Data.Set涉及重新平衡,这对我来说非常复杂,我怀疑有类似于列表优化的东西.我尝试阅读Set docs引用的论文,但无法用它来回答我的问题.

那么:如何在一个(纯)函数式语言中将元素插入二叉树中是O(log(n))?

complexity-theory haskell referential-transparency

8
推荐指数
2
解决办法
610
查看次数