Haskell(使用GHC编译器)比你期望的要快很多.如果使用得当,它可以与低级语言保持密切联系.(Haskellers最喜欢的事情是尝试在C的5%范围内(或者甚至击败它,但这意味着你使用的是低效的C程序,因为GHC将Haskell编译为C).)我的问题是,为什么?
Haskell是声明性的,基于lambda演算.机器架构显然势在必行,粗略地基于图灵机.实际上,Haskell甚至没有具体的评估顺序.此外,您不必处理机器数据类型,而是始终生成代数数据类型.
最奇怪的是更高阶函数.你会认为动态创建函数并抛出它们会使程序变慢.但是使用更高阶函数实际上使Haskell更快.实际上,似乎要优化Haskell代码,你需要使它更优雅和抽象,而不是更像机器.如果Haskell的更高级功能没有改进,它们似乎甚至都不会影响它的性能.
很抱歉,如果这听起来不错,但这是我的问题:为什么Haskell(使用GHC编译)如此之快,考虑到它的抽象性质和与物理机器的差异?
注意:我说C和其他命令式语言有点类似于图灵机的原因(但不是Haskell类似于Lambda微积分)是因为在命令式语言中,你有一个有限数量的状态(也就是行号) ,以及磁带(ram),以便状态和当前磁带确定对磁带做什么.有关从图灵机到计算机的过渡,请参阅维基百科条目,图灵机等效项.
performance haskell lambda-calculus ghc higher-order-functions
我已经学会了foldLeft和之间的基本区别reduceLeft
foldLeft:
reduceLeft:
还有其他区别吗?
有两种方法具有相似功能的任何特定原因?
例如,我想从这个字符串中的元素创建一个数组:
$str = 'red, green, blue ,orange';
Run Code Online (Sandbox Code Playgroud)
我知道你可以爆炸并循环它们并修剪:
$arr = explode(',', $str);
foreach ($arr as $value) {
$new_arr[] = trim($value);
}
Run Code Online (Sandbox Code Playgroud)
但我觉得有一种单线方法可以解决这个问题.有任何想法吗?
我正在尝试使用ES6箭头功能.filter来回归成年人(Jack&Jill).看来我不能使用if语句.
在ES6中我需要知道什么?
var family = [{"name":"Jack", "age": 26},
{"name":"Jill", "age": 22},
{"name":"James", "age": 5 },
{"name":"Jenny", "age": 2 }];
let adults = family.filter(person => if (person.age > 18) person); // throws error
(8:37) SyntaxError: unknown: Unexpected token (8:37)
|let adults = family.filter(person => if (person.age > 18) person);
Run Code Online (Sandbox Code Playgroud)
我工作的ES5示例:
let adults2 = family.filter(function (person) {
if (person.age > 18) { return person; }
});
Run Code Online (Sandbox Code Playgroud) 通过阅读这篇经典论文,我坚持认为是paramorphisms.不幸的是,该部分非常薄,维基百科页面没有说什么.
我的Haskell翻译是:
para :: (a -> [a] -> b -> b) -> b -> [a] -> b
para f base = h
where
h [] = base
h (x:xs) = f x xs (h xs)
Run Code Online (Sandbox Code Playgroud)
但我不认为 - 我对类型签名或期望的结果没有任何直觉.
什么是paramorphism,什么是行动中的一些有用的例子?
是的,我已经看过这些 问题了,但是它们并没有直接涵盖paramorphisms,只指向可能有用作为参考的资源,而不是学习资料.
recursion haskell functional-programming higher-order-functions
Python具有语法上的甜蜜列表理解:
S = [x**2 for x in range(10)]
print S;
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Run Code Online (Sandbox Code Playgroud)
在PHP中我需要做一些循环:
$output = array();
$Nums = range(0,9);
foreach ($Nums as $num)
{
$out[] = $num*=$num;
}
print_r($out);
Run Code Online (Sandbox Code Playgroud)
要得到:
数组([0] => 0 [1] => 1 [2] => 4 [3] => 9 [4] => 16 [5] => 25 [6] => 36 [7] => 49 [8] => 64 [9] => 81)
反正有没有在PHP中获得类似的列表理解语法?无论如何使用PHP 5.3中的任何新功能吗?
谢谢!
php arrays language-comparisons list-comprehension higher-order-functions
你如何在PHP中翻转90度(转置)多维数组?例如:
// Start with this array
$foo = array(
'a' => array(
1 => 'a1',
2 => 'a2',
3 => 'a3'
),
'b' => array(
1 => 'b1',
2 => 'b2',
3 => 'b3'
),
'c' => array(
1 => 'c1',
2 => 'c2',
3 => 'c3'
)
);
$bar = flipDiagonally($foo); // Mystery function
var_dump($bar[2]);
// Desired output:
array(3) {
["a"]=>
string(2) "a2"
["b"]=>
string(2) "b2"
["c"]=>
string(2) "c2"
}
Run Code Online (Sandbox Code Playgroud)
你会如何实施flipDiagonally()?
编辑:这不是作业.我只是想看看是否有任何SOers比最明显的路线更具创造性的解决方案.但是,由于一些人抱怨这个问题太容易了,那么一个适用于第 n 维数组的更通用的解决方案呢?
即如何编写函数以便:
$foo[j][k][...][x][y][z] …Run Code Online (Sandbox Code Playgroud) 我刚刚在React中查看了HOC.他们很酷.但是,不是简单地包装组件就能达到相同的效果吗?
这个简单的HOC将状态作为属性传递给ComposedComponent
const HOC = ComposedComponent => class extends React.Component {
... lifecycle, state, etc;...
render() {
return (<ComposedComponent {...this.state} />);
}
}
Run Code Online (Sandbox Code Playgroud)
此组件将state作为属性传递给子组件
class ParentComponent extends React.Component {
... lifecycle, state, etc;...
render() {
return (
<div>
{React.cloneElement(this.props.children, { ...this.state })}
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
尽管两者之间的使用略有不同,但它们似乎都可以重复使用.
通过this.props.children,HOC和组成组件之间的真正区别在哪里?是否有例子只能使用其中一个?使用HOC是一种更好的做法.这些只是您选择自己喜欢的风味的选择吗?
我可以在R中创建一个compose运算符:
`%c%` = function(x,y)function(...)x(y(...))
Run Code Online (Sandbox Code Playgroud)
要像这样使用:
> numericNull = is.null %c% numeric
> numericNull(myVec)
[2] TRUE FALSE
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有一套官方功能来完成这类事情以及其他操作,比如在R.中进行currying.这主要是为了减少代码中括号,函数关键字等的数量.
我的咖喱功能:
> curry=function(...){
z1=z0=substitute(...);z1[1]=call("list");
function(...){do.call(as.character(z0[[1]]),
as.list(c(eval(z1),list(...))))}}
> p = curry(paste(collapse=""))
> p(letters[1:10])
[1] "abcdefghij"
Run Code Online (Sandbox Code Playgroud)
这对于例如聚合来说特别好:
> df = data.frame(l=sample(1:3,10,rep=TRUE), t=letters[1:10])
> aggregate(df$t,df["l"],curry(paste(collapse="")) %c% toupper)
l x
1 1 ADG
2 2 BCH
3 3 EFIJ
Run Code Online (Sandbox Code Playgroud)
我发现它比以下更优雅和可编辑:
> aggregate(df$t, df["l"], function(x)paste(collapse="",toupper(x)))
l x
1 1 ADG
2 2 BCH
3 3 EFIJ
Run Code Online (Sandbox Code Playgroud)
基本上我想知道 - 这已经为R做过吗?
Clojure很棒,我们都知道这一点,但这不是重点.我想知道以类似Haskell的方式创建和管理高阶函数的惯用方法是什么.在Clojure中,我可以执行以下操作:
(defn sum [a b] (+ a b))
Run Code Online (Sandbox Code Playgroud)
但是(sum 1)不返回函数:它会导致错误.当然,你可以这样做:
(defn sum
([a] (partial + a))
([a b] (+ a b)))
Run Code Online (Sandbox Code Playgroud)
在这种情况下:
user=> (sum 1)
#<core$partial$fn__3678 clojure.core$partial$fn__3678@1acaf0ed>
user=> ((sum 1) 2)
3
Run Code Online (Sandbox Code Playgroud)
但这似乎不是正确的方法.有任何想法吗?
我不是在谈论实现这个sum功能,我正在谈论更高层次的抽象.是否有任何惯用模式可供遵循?有些宏?是定义宏的最佳方式还是有替代解决方案?
php ×3
arrays ×2
haskell ×2
clojure ×1
currying ×1
ecmascript-6 ×1
explode ×1
fold ×1
ghc ×1
javascript ×1
performance ×1
r ×1
react-redux ×1
react-router ×1
reactjs ×1
recursion ×1
scala ×1
trim ×1