haskell – 你发现你仍然需要变量,你可以改变,如果是为什么?

我听说过对函数式语言的一个论点是,单个赋值的编码太难了,或者至少比“正常”的编程困难得多。

但是通过我的代码,我意识到,我真的没有很多(任何?)使用模式,不能使用单一的赋值形式,如果你写在一个合理的现代语言。

那么在一个范围的单一调用中变化的变量的用例是什么?请记住,在这种情况下,循环索引,参数和在调用之间不同的其他范围绑定值不是多个赋值(除非你因为某种原因必须在体中更改它们),并且假设你正在写一些东西足够高的汇编语言级别,在那里你可以写的东西

values.sum

或(如果不提供金额)

function collection.sum --> inject(zero, function (v,t) --> t+v )

x = if a > b then a else b

要么

n = case s 
  /^\d*$/ : s.to_int
  ''      : 0
  '*'     : a.length
  '?'     : a.length.random
  else    fail "I don't know how many you want"

当你需要,并有列表推导,地图/收集,等等可用。

你发现你在这样的环境中仍然需要/需要可变变量,如果是这样,为什么?

为了澄清,我不是要求反驳对SSA形式的反对,而是要求那些反对适用的具体例子。我正在寻找一些清晰和简洁的可变变量的代码,如果没有它们就不能被写入。

我最喜欢的例子到目前为止(和最好的反对,我期望他们):

> Paul Johnson的Fisher-Yates algorithm答案,当你包括大O约束时,这是相当强大。但是,如果catulahoops指出,大O问题不是绑定到SSA问题,而是有可变的数据类型,并且留出来的算法可以在SSA中写得相当清楚:

 shuffle(Lst) ->
     array:to_list(shuffle(array:from_list(Lst), erlang:length(Lst) - 1)).
 shuffle(Array, 0) -> Array;
 shuffle(Array, N) ->
     K = random:uniform(N) - 1,
     Ek = array:get(K, Array),
     En = array:get(N, Array),
     shuffle(array:set(K, En, array:set(N, Ek, Array)), N-1).

> jpalecek的area of a polygon示例:

def area(figure : List[Point]) : Float = {
  if(figure.empty) return 0
  val last = figure(0)
  var first= figure(0)
  val ret = 0
  for (pt <- figure) {
    ret+=crossprod(last - first, pt - first)
    last = pt
  }
  ret
}

这可能仍然写作类似:

def area(figure : List[Point]) : Float = {
    if figure.length < 3
        0
      else
        var a = figure(0)
        var b = figure(1)
        var c = figure(2)
        if figure.length == 3
            magnitude(crossproduct(b-a,c-a))
          else 
            foldLeft((0,a,b))(figure.rest)) { 
               ((t,a,b),c) => (t+area([a,b,c]),a,c)
               }

或者,由于一些人反对这种制剂的密度,它可以重铸:

def area([])    = 0.0   # An empty figure has no area
def area([_])   = 0.0   # ...nor does a point
def area([_,_]) = 0.0   # ...or a line segment
def area([a,b,c]) =     # The area of a triangle can be found directly
    magnitude(crossproduct(b-a,c-a))
def area(figure) =      # For larger figures, reduce to triangles and sum
    as_triangles(figure).collect(area).sum

def as_triangles([])      = []  # No triangles without at least three points
def as_triangles([_])     = []
def as_triangles([_,_])   = []
def as_triangles([a,b,c | rest) = [[a,b,c] | as_triangles([a,c | rest])]

>关于使用不可变结构实现O(1)队列的困难的公主点很有趣(并且可能提供了一个引人注目的例子的基础),但是如所述的,它基本上涉及数据结构的可变性,而不是直接关于多重赋值问题。
>我对Eratosthenes筛选的答案感兴趣,但不相信。正确的大O,拉出许多素数,你想要的发电机在他引用的文章看起来不容易实现正确与否与SSA。

好,感谢大家的努力。由于大多数答案证明是1)基于可变数据结构,而不是单一赋值,以及2)对于它们关于单一赋值形式的程度,容易被本领域技术人员反驳,我将要从我的谈话和/或重组(可能有备份作为一个讨论主题,在不太可能的情况下,我用完的话,我用完了时间)。

再次感谢。

我从来没有确定这样的情况。虽然你总是可以发明新的名字,如转换为SSA形式,我发现很容易和自然的每个值都有自己的名字。像Haskell这样的语言给了我很多选择要命名的值,和两个不同的地方放置名称绑定(let和where)。我发现单一任务形式相当自然,而不是很困难。

我偶尔会错过能够有指向堆上的可变对象的指针。但这些东西没有名字,所以它不一样的反对。 (我还发现,当我在堆上使用可变对象时,我倾向于写更多的错误!)

http://stackoverflow.com/questions/610956/do-you-find-you-still-need-variables-you-can-change-and-if-so-why

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:haskell – 你发现你仍然需要变量,你可以改变,如果是为什么?