我正在努力完全理解Haskell的所有概念.
代数数据类型在哪些方面类似于泛型类型,例如在C#和Java中?它们有何不同?无论如何,他们有什么代数呢?
我熟悉通用代数及其环和字段,但我对Haskell的类型如何工作只有一个模糊的概念.
haskell types functional-programming algebraic-data-types data-structures
这些术语似乎有 不同的定义,但我总是想到一个暗示另一个; 当表达式是引用透明但不纯粹时,我无法想到任何情况,反之亦然.
维基百科为这些概念维护单独的文章并说:
从参考透明度:
如果表达式中涉及的所有函数都是纯函数,则表达式是引用透明的.此外,如果丢弃它们的值并且它们的副作用无关紧要,则表达式中可以包含一些不纯的函数.
来自纯粹的表达:
构造纯表达式需要纯函数.[...]纯表达通常被称为引用透明.
我发现这些陈述令人困惑.如果副作用所谓的"非纯函数"是微不足道的,足以让不执行他们(即替换其这种函数的调用值没有实质性改变程序),它是一样的,如果它的是纯粹的第一名,不是吗?
有没有更简单的方法来理解纯表达式和引用透明的表达式之间的差异(如果有的话)?如果存在差异,则可以理解清楚地表明它的示例表达.
language-agnostic functional-programming side-effects referential-transparency purely-functional
这可能听起来像一个奇怪的问题,但有没有办法在Java 8中引用Lambda的标准无操作(即null操作,空模式方法,无操作,无操作方法)方法.
目前,我有一个方法,需要一个,比方说,void foo(Consumer<Object>)我想给它一个无操作,我必须声明:
foo(new Consumer<Object>() {
public void accept(Object o) {
// do nothing
}
}
Run Code Online (Sandbox Code Playgroud)
在哪里我希望能够做到这样的事情:
foo(Object::null)
Run Code Online (Sandbox Code Playgroud)
代替.有类似存在吗?
不确定多参数方法如何工作 - 也许这是Java中lambdas的缺陷.
如果我错了,请纠正我,但似乎Haskell中的代数数据类型在许多你将在OO语言中使用类和继承的情况下都很有用.但是有一个很大的区别:一旦声明了代数数据类型,它就无法在其他地方扩展.它是"封闭的".在OO中,您可以扩展已定义的类.例如:
data Maybe a = Nothing | Just a
Run Code Online (Sandbox Code Playgroud)
以后我无法以某种方式为此类型添加另一个选项而不修改此声明.那么这个系统有什么好处呢?似乎OO方式可以更加可扩展.
flatMap对集合非常有用,但javascript不提供Array.prototype.map.为什么?
有没有办法flatMap在javascript中以简单有效的方式模拟,无需flatMap手动定义?
Jamie Zawinski在他的(1997)文章"java sucks"中使用了这个术语,好像你应该知道这意味着什么:
我真的很讨厌缺乏向下的乐趣; 匿名类是一个蹩脚的替代品.(我可以没有长寿的闭包,但我发现缺少功能指针是一个巨大的痛苦.)
它似乎是Lisper的俚语,我可以在这里找到以下简短的定义,但不知何故,我想我仍然没有得到它:
许多闭包只在它们引用的绑定范围内使用; 这些在Lisp的说法中被称为"向下的funargs".
如果不是Steve Yegge,我现在感觉很愚蠢,但似乎可以问:
Jamie Zawinski是一位英雄.一个活生生的传奇 [...] 一个人可以使用"向下的funargs"一词,然后瞪着你,只是敢于要求他解释它,你克里汀.
那么在这里有一个Lisper可以为我这样的C风格程序员编译吗?
我在与Scheme和类似地区相关的代码和文档中的很多地方都遇到了"thunk"这个词.我猜它是一个过程的通用名称,它有一个正式的参数.那是对的吗?如果是,那还有更多吗?如果没有,拜托?
例如.在SRFI 18中,在"程序"部分.
本周末,我决定尝试一些Scala和Clojure.我精通面向对象的编程,因此Scala很容易学习语言,但想尝试函数式编程.这是它变得艰难的地方.
我似乎无法进入编写函数的模式.作为一名专业的功能程序员,您如何解决问题?
给定一个值列表和一个定义的求和周期,您将如何生成列表中简单移动平均值的新列表?
例如:给定列表values(2.0,4.0,7.0,6.0,3.0,8.0,12.0,9.0,4.0,1.0)和period4,函数应该返回:(0.0,0.0,0.0,4.75,5.0,6.0, 7.25,8.0,8.25,6.5)
在花了一天时间考虑它之后,我在Scala中想出的最好的是:
def simpleMovingAverage(values: List[Double], period: Int): List[Double] = {
(for (i <- 1 to values.length)
yield
if (i < period) 0.00
else values.slice(i - period, i).reduceLeft(_ + _) / period).toList
}
Run Code Online (Sandbox Code Playgroud)
我知道这是非常低效的,我宁愿做类似的事情:
where n < period: ma(n) = 0
where n = period: ma(n) = sum(value(1) to value(n)) / period
where n > period: man(n) = ma(n -1) - (value(n-period) / period) + (value(n) / period)
Run Code Online (Sandbox Code Playgroud)
现在,这将很容易以一种命令式的方式完成,但我不能为我的生活弄清楚如何在功能上表达.
Haskell被称为"纯函数式语言".
在这种情况下,"纯粹"意味着什么?这对程序员有什么影响?
haskell ×3
oop ×2
types ×2
clojure ×1
closures ×1
java ×1
java-8 ×1
javascript ×1
lambda ×1
lisp ×1
object ×1
scala ×1
scheme ×1
side-effects ×1
terminology ×1
type-systems ×1