Car*_*ers 42 haskell functional-programming
我经常听说函数式编程解决了许多在程序/命令式编程中难以解决的问题.但我也听说过程序编程自然很擅长的其他一些问题并不是很好.
在我打开关于Haskell的书并深入研究函数式编程之前,我至少想了解一下我能用它的基本概念(在本书的例子之外).那么,函数式编程擅长的是什么呢?它不适合的问题是什么?
到目前为止,我已经得到了一些很好的答案.我迫不及待地开始学习Haskell - 我只需要等到我掌握C :)
函数式编程很棒的原因:
函数式编程困难的领域:
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)
函数式编程对并行编程很有用.事实上,您不依赖于函数式编程的状态更改意味着各种处理器/内核不会互相踩踏.因此,对压缩,图形效果和一些复杂数学任务等并行性很好的算法类型通常也是函数式编程的良好候选者.事实上,多核CPU和GPU只是越来越受欢迎,这也意味着对这类产品的需求将会增长.
它可能与函数式编程没有直接联系,但在数据结构的设计和实现中没有任何东西胜过联合.让我们比较两个等价的代码:
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)