功能编程最好/最差的问题是什么?

Car*_*ers 42 haskell functional-programming

我经常听说函数式编程解决了许多在程序/命令式编程中难以解决的问题.但我也听说过程序编程自然很擅长的其他一些问题并不是很好.

在我打开关于Haskell的书并深入研究函数式编程之前,我至少想了解一下我能用它的基本概念(在本书的例子之外).那么,函数式编程擅长的是什么呢?它不适合的问题是什么?

更新

到目前为止,我已经得到了一些很好的答案.我迫不及待地开始学习Haskell - 我只需要等到我掌握C :)

函数式编程很棒的原因:

  • 非常简洁和简洁 - 它可以用简短的,未经过混淆的陈述表达复杂的想法.
  • 比命令式语言更容易验证 - 在系统安全至关重要的地方很好.
  • 函数的纯度和数据的不变性使得并发编程更加合理.
  • 非常适合脚本编写和编写程序(我很高兴知道为什么).
  • 数学相关的问题简单而精美地解决了.

函数式编程困难的领域:

  • 有争议的:网络应用程序(虽然我猜这取决于应用程序).
  • 桌面应用程序(虽然它可能取决于语言,F#会擅长这个不是吗?).
  • 任何性能至关重要的东西,比如游戏引擎.
  • 任何涉及大量程序状态的东西.

Ale*_*own 13

由于存在更高级别的函数(map,lfold,grep)和类型推断,函数式编程擅长简洁.

出于同样的原因,它在通用编程方面也很出色,并且进一步提高了在简短陈述中表达复杂想法的能力,而没有混淆.

我很欣赏这些属性,因为它们使交互式编程变得合理.(例如R,SML).

我怀疑功能编程也可以更容易地被其他编程方法验证,这在安全关键系统(核电站和医疗设备)中是有利的.

  • 类型推断不是函数式编程的属性. (8认同)
  • 并非所有函数式语言都具有类型推断,并且存在具有类型推断的命令式语言. (2认同)

Hao*_*Lim 11

我会说功能编程适合解决问题,例如AI问题,数学问题(这太简单了),游戏引擎但不太适合GUI和自定义控件开发或需要花哨UI的桌面应用程序.我发现通过以下方式思考是直观的(虽然它可能会泛滥太多):

            Back-end   Front-end
Low-level   C          C++
High-level  FP         VB, C#
Run Code Online (Sandbox Code Playgroud)

  • 我几乎给你+1,直到我注意到那里列出了VB.不,我不认为你错了,但我只是讨厌VB那么多. (13认同)

Ste*_*ham 6

函数式编程对并行编程很有用.事实上,您不依赖于函数式编程的状态更改意味着各种处理器/内核不会互相踩踏.因此,对压缩,图形效果和一些复杂数学任务等并行性很好的算法类型通常也是函数式编程的良好候选者.事实上,多核CPU和GPU只是越来越受欢迎,这也意味着对这类产品的需求将会增长.


Jul*_*iet 6

它可能与函数式编程没有直接联系,但在数据结构的设计和实现中没有任何东西胜过联合.让我们比较两个等价的代码:

F#:

type 'a stack = Cons of 'a * stack | Nil
let rec to_seq = function
    | Nil -> Seq.empty;
    | Cons(hd, tl) -> seq { yield hd; yield! to_seq tl }
let rec append x y =
    match x with
    | Nil -> y
    | Cons(hd, tl) -> Cons(hd, append tl y)
let x = Cons(1, Cons(2, Cons(3, Cons(4, Nil))))
let y = Cons(5, Cons(6, Cons(7, Cons(8, Nil))))
let z = append x y
to_seq z |> Seq.iter (fun x -> printfn "%i" x)

Java的:

interface IStack<T> extends Iterable<T>
{
    IStack<T> Push(T value);
    IStack<T> Pop();
    T Peek();
    boolean IsEmpty();
}
final class EmptyStack<T> implements IStack<T>
{
    public boolean IsEmpty() { return true; }
    public IStack<T> Push(T value) { return Stack.cons(value, this); }
    public IStack<T> Pop() { throw new Error("Empty Stack"); }
    public T Peek() { throw new Error("Empty Stack"); }
    public java.util.Iterator<T> iterator()
    {
        return new java.util.Iterator<T>()
        {
            public boolean hasNext() { return false; }
            public T next() { return null; }
            public void remove() { }
        };
    }
}
final class Stack<T> implements IStack<T>
{
    public static <T> IStack<T> cons(T hd, IStack<T> tl) { return new Stack<T>(hd, tl); }
    public static <T> IStack<T> append(IStack<T> x, IStack<T> y)
    {
        return x.IsEmpty() ? y : new Stack(x.Peek(), append(x.Pop(), y));
    }
    private final T hd;
    private final IStack<T> tl;
    private Stack(T hd, IStack<T> tl)
    {
        this.hd = hd;
        this.tl = tl;
    }
    public IStack<T> Push(T value) { return new <T> Stack(value, this); }
    public IStack<T> Pop() { return this.tl; }
    public T Peek() { return this.hd; }
    public boolean IsEmpty() { return false; }
    public java.util.Iterator<T> iterator()
    {
        final IStack<T> outer = this;
        return new java.util.Iterator<T>()
        {
            private IStack<T> current = outer;
            public boolean hasNext() { return !current.IsEmpty(); }
            public T next()
            {
                T hd = current.Peek();
                current = current.Pop();
                return hd;
            }
            public void remove() { }
        };
    }
}
public class Main
{
    public static void main(String[] args)
    {
        IStack<Integer> x = Stack.cons(1, Stack.cons(2, Stack.cons(3, Stack.cons(4, new EmptyStack()))));
        IStack<Integer> y = Stack.cons(5, Stack.cons(6, Stack.cons(7, Stack.cons(8, new EmptyStack()))));
        IStack<Integer> z = Stack.append(x, y);

        for (Integer num : z)
        {
            System.out.printf("%s ", num);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为,这更像是一个强大的类型系统,而不是函数式编程的特定结果.另一方面,在功能编程环境之外没有太多真正好的类型系统,也没有很多功能编程环境而没有仔细考虑类型系统. - 特别是Java是一个糟糕的例子,设计人员从现有的模型(C++)开始,删除了他们不喜欢的东西,而不是将类型系统设计为富有表现力和*可读*! (5认同)