我一直在阅读关于组合器的信息,看看它们有多大用处(例如,在Haskell的Parsec中).我的问题是,我不太确定如何实际使用它们.
以下是问题的概述:可以生成,过滤和修改分布.可以组合分布以创建新的分布.
基本接口是(伪Haskell类型术语):
generator:: parameters -> distribution
selector:: parameters -> (distribution -> distribution)
modifier:: parameters -> (distribution -> distribution)
Run Code Online (Sandbox Code Playgroud)
现在,我认为我看到了三个组合器:
combine:: generator -> generator -> generator
filter:: generator -> selector -> generator
modify:: generator -> modifier -> generator
Run Code Online (Sandbox Code Playgroud)
这些实际上是组合器吗?组合器是否有意义/是否还有其他明显的组合器我缺少?
谢谢你的建议.
haskell functional-programming combinators higher-order-functions
我是Haskell的新手,也是函数式编程的新手.在其他(除了Haskell)语言中,lambda表单通常非常有用.
例如,在Scheme中:
(define (deriv-approx f)
(lambda (h x)
(/ (- (f (+ x h)
(f x)
h)))
Run Code Online (Sandbox Code Playgroud)
将创建一个闭包(在函数f上)以逼近导数(值x,间隔为h).但是,由于部分应用,在Haskell中似乎不需要使用lambda形式:
deriv-approx f h x = ( (f (x + h)) - (f x) ) / h
Run Code Online (Sandbox Code Playgroud)
在Haskell中需要lambda形式的一些例子是什么?
编辑:用'lambda form'替换'closure'
有两个简单的类Int作为参数:
case class Foo(i: Int)
class Bar(j: Int)
Run Code Online (Sandbox Code Playgroud)
我可以说:
List(1,2,3) map Foo
Run Code Online (Sandbox Code Playgroud)
哪个工作正常,相当于更冗长:
List(1,2,3) map {Foo(_)}
Run Code Online (Sandbox Code Playgroud)
但是Bar(因为它不是案例类?)不能在同一个构造中使用:
List(1,2,3) map Bar
error: not found: value Bar
List(1,2,3) map Bar
^
Run Code Online (Sandbox Code Playgroud)
是否有一些特殊的语法来引用任何构造函数并利用eta扩展?List(1,2,3) map {new Bar(_)}与...相比似乎有点冗长Foo.
我正在完成20个中级Haskell练习,这是一个非常有趣的练习.它涉及到执行类型类的各种实例Functor和Monad(而这需要职能FunctorS和MonadS作为参数),但像可爱的名字Furry和Misty掩饰我们正在做什么(一些有趣的代码使).
我一直试图以无点的方式做一些这样的事情,我想知道是否有一个将点 - 完全(?)定义转变为无点定义的一般方案.例如,以下是类型类Misty:
class Misty m where
unicorn :: a -> m a
banana :: (a -> m b) -> m a -> m b
Run Code Online (Sandbox Code Playgroud)
(函数unicorn和banana是,return并且>>=,如果不是很明显),这是我的apple(相当于flip ap)的实现:
apple :: (Misty m) => m a -> m (a -> b) -> m b
apple x f = banana (\g -> banana (unicorn …Run Code Online (Sandbox Code Playgroud) 使用高阶函数和Lambda会使运行时间和内存效率更好还是更差?例如,要乘以列表中的所有数字:
nums = [1,2,3,4,5]
prod = 1
for n in nums:
prod*=n
Run Code Online (Sandbox Code Playgroud)
VS
prod2 = reduce(lambda x,y:x*y , nums)
Run Code Online (Sandbox Code Playgroud)
除了较少的代码行/使用功能方法之外,HOF版本是否比循环版本有任何优势?
编辑:
我无法将此作为答案添加,因为我没有所需的声誉.我根据@DSM的建议使用timeit绑定了循环和HOF方法
def test1():
s= """
nums = [a for a in range(1,1001)]
prod = 1
for n in nums:
prod*=n
"""
t = timeit.Timer(stmt=s)
return t.repeat(repeat=10,number=100)
def test2():
s="""
nums = [a for a in range(1,1001)]
prod2 = reduce(lambda x,y:x*y , nums)
"""
t = timeit.Timer(stmt=s)
return t.repeat(repeat=10,number=100)
Run Code Online (Sandbox Code Playgroud)
这是我的结果:
Loop:
[0.08340786340144211, 0.07211491653462579, 0.07162720686361926, 0.06593182661083438, 0.06399049758613146, 0.06605228229559557, 0.06419744588664211, 0.0671893658461038, 0.06477527090075941, …Run Code Online (Sandbox Code Playgroud) 如何包装递归函数,包括递归调用?例如,给定foo和wrap:
def foo(x):
return foo(x - 1) if x > 0 else 1
def wrap(f):
def wrapped(*args, **kwargs):
print "f was called"
return f(*args, **kwargs)
return wrapped
Run Code Online (Sandbox Code Playgroud)
wrap(foo)(x)只会"f was called"在第一次通话时输出.递归调用仍然可以解决foo().
我不介意猴子修补,或在内部戳.我不打算将这个代码添加到下一个核弹头处理程序中,所以即使这是一个坏主意,我也想实现这个效果.
编辑:例如,修补foo.func_globals以覆盖foo.__name__工作?如果它总是这样,我应该注意任何副作用?
当我在第5章遇到这个时,我正在阅读Eloquent JavaScript:
你可以拥有创建新功能的功能.
Run Code Online (Sandbox Code Playgroud)function greaterThan(n) { return function(m) { return m > n; }; } var greaterThan10 = greaterThan(10);你可以拥有改变其他功能的功能.
Run Code Online (Sandbox Code Playgroud)function noisy(f) { return function(arg) { console.log("calling with", arg); var val = f(arg); console.log("called with", arg, "- got", val); return val; }; } noisy(Boolean)(0); //->calling with 0 //->called with 0 - got false
我的问题是:
我有一连串的if/ else if陈述,这不是自我解释。我想用清晰的解释性名称将每个提取到其自己的函数中,然后将这些函数链接起来。
如何在Scala中途停止呼叫链?
这是一个代码示例:
// actual code
for( klass <- program.classes ) {
if ( complicated boolean ) { //checkVars
error1
} else if ( complicated boolean ) { //checkMethods
error2
} else if ( ... ) { //...
error3
} else {
complicated good case code
}
}
Run Code Online (Sandbox Code Playgroud)
// wanted
for( klass <- program.classes ) {
(checkName
andThen checkVars
andThen checkMethods
andThen addToContext) (klass)
// where the chaining stops if a check fails
}
Run Code Online (Sandbox Code Playgroud) 我知道Swift的高阶函数,如Map,Filter,Reduce和FlatMap,但是我不知道有什么像'All'或'Any'那样返回一个布尔值,在枚举时对正测试进行短路.结果.
例如,isFulfilled假设您拥有10,000个对象的集合,每个对象都有一个被调用的属性,并且您希望查看该集合中是否有任何对象isFulfilled设置为false.在C#中,您可以使用myObjects.Any(obj -> !obj.isFulfilled)并且当该条件被命中时,它会使枚举的其余部分短路并立即返回true.
Swift中有没有这样的东西?
我正在尝试访问我在其中使用reduce函数的数组的长度,但是我似乎无法做到,有没有人知道是否可以访问数组任何高阶函数内的对象?
PS:我试过this但没有成功;
PSS:我想使用reduce函数计算平均评级,所以我使用reduce来对数组中的所有值求和,并将这些相同的值除以数组长度,如下所示:
let averageRating = watchList
.filter(movie => movie.Director === 'Christopher Nolan')
.map(x => parseFloat(x.imdbRating))
.reduce((total, current) => total + (current / 'array length'));
Run Code Online (Sandbox Code Playgroud)
你猜对了'数组长度',数组长度.
PSSS:试过
var averageRating = watchList
.filter(movie => movie.Director === 'Christopher Nolan')
.map(x => parseFloat(x.imdbRating))
.reduce((total, current, index, arr) => total + (current / arr.length));
Run Code Online (Sandbox Code Playgroud)
但是数组长度随着数组的减少而不断变化,所以它不适用于我的目的.
haskell ×3
combinators ×2
javascript ×2
python ×2
scala ×2
arrays ×1
closures ×1
constructor ×1
pointfree ×1
scheme ×1
swift ×1