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
功能,我正在谈论更高层次的抽象.是否有任何惯用模式可供遵循?有些宏?是定义宏的最佳方式还是有替代解决方案?
你可以在foldRight方面正确折叠左边吗?反过来怎么样?
在作者提供的解决方案中,他们提供了如下实现:
def foldRightViaFoldLeft_1[A,B](l: List[A], z: B)(f: (A,B) => B): B =
foldLeft(l, (b:B) => b)((g,a) => b => g(f(a,b)))(z)
def foldLeftViaFoldRight[A,B](l: List[A], z: B)(f: (B,A) => B): B =
foldRight(l, (b:B) => b)((a,g) => b => g(f(b,a)))(z)
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我追踪这个解决方案并让我理解这实际上是如何实现foldl实现的折叠,反之亦然?
谢谢
functional-programming scala currying fold higher-order-functions
给定一个DoSomething
采用(无参数)函数的方法并以某种方式处理它.有没有更好的方法为参数的函数创建"重载"而不是下面的代码片段?
public static TResult DoSomething<TResult>(Func<TResult> func)
{
//call func() and do something else
}
public static TResult DoSomething<T0, TResult>(
Func<T0, TResult> func,
T0 arg0)
{
return DoSomething(() => func(arg0));
}
public static TResult DoSomething<T0, T1, TResult>(
Func<T0, T1, TResult> func,
T0 arg0, T1 arg1)
{
return DoSomething(arg => func(arg, arg1), arg0);
}
public static TResult DoSomething<T0, T1, T2, TResult>(
Func<T0, T1, T2, TResult> func,
T0 arg0, T1 arg1, T2 arg2)
{
return DoSomething(arg => func(arg, arg1, arg2), arg0); …
Run Code Online (Sandbox Code Playgroud) 可以使用以下结构在Mathematica中实现有限形式的Currying:
f[a_][b_][c_] := (a^2 + b^2)/c^2
Run Code Online (Sandbox Code Playgroud)
允许一个人做,例如:
f[4][3] /@ Range@5
Run Code Online (Sandbox Code Playgroud)
{25, 25/4, 25/9, 25/16, 1}
有一个问题:Attributes
只适用于第一个(一组)参数.考虑:
ClearAll[f]
SetAttributes[f, HoldAllComplete]
f[a_][b_][c_] :=
{ToString@Unevaluated@a,
ToString@Unevaluated@b,
ToString@Unevaluated@c}
f[2 + 2][ 8/4 ][3 + 5]
Run Code Online (Sandbox Code Playgroud)
{"2 + 2", "2", "8"}
我的意图是返回"8 / 4"
,并"3 + 5"
在列表中.
所以:
有没有办法将属性扩展到此构造?
是否有其他方便的结构来实现这一目标?
除了属性之外,还有其他方法可以扩展Mathematica中的Currying吗?
好吧,所以我不是Haskell程序员,但我对Haskell背后的许多想法非常感兴趣,并且我正在研究它.但是我被困在第一个方面:我似乎无法绕过Monads,这似乎是相当基础的.我知道有一百万个关于SO的问题要求解释Monads,所以我会更加具体地说明了什么在困扰我:
我读了这篇优秀的文章(Javascript中的介绍),并认为我完全了解Monads.然后我读了Monads上的维基百科条目,看到了:
多态类型(M t)→(t→M u)→(M u)的绑定操作,其中Haskell由中缀运算符表示>> =.它的第一个参数是monadic类型的值,它的第二个参数是一个函数,它从第一个参数的基础类型映射到另一个monadic类型,其结果是在其他monadic类型中.
好的,在我引用的文章中,bind是一个仅占用一个参数的函数.维基百科说两个.我认为我对Monads的理解如下:
但是肯定有一些错误,因为我的bind概念需要一个参数:一个函数.但是(根据维基百科)Haskell的绑定实际上有两个参数!我的错误在哪里?
有很多关于如何理解函数的教程,以及stackoverflow中的许多问题.然而,在阅读了The Little Schemer,几本书,教程,博客文章和stackoverflow主题之后,我仍然不知道这个简单问题的答案:"有什么关系?" 我明白如何理解一个功能,而不是"为什么?" 在它背后.
有人可以向我解释一下curried函数的实际用法(在每个函数只允许一个参数的语言之外,使用currying的必要性当然非常明显.)
编辑:考虑到TLS的一些例子,有什么好处
(define (action kind)
(lambda (a b)
(kind a b)))
Run Code Online (Sandbox Code Playgroud)
而不是
(define (action kind a b)
(kind a b))
Run Code Online (Sandbox Code Playgroud)
我只能看到更多的代码,没有更多的灵活性......
我需要一个js sum函数来像这样工作:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
Run Code Online (Sandbox Code Playgroud)
我听说不能这样做.但是听说如果加+
在前面sum
就可以做到.喜欢+sum(1)(2)(3)(4)
.
有关如何做到这一点的任何想法?
请原谅我,如果已经在别处问过这个问题.我有一个涉及函数值和隐式参数的Scala语法问题.
我很自在地使用Scala的currying功能.例如,如果我有一个sum函数,并希望使第二个参数隐含:
scala> def sum(a: Int)(implicit b: Int) = a + b
sum: (a: Int)(implicit b: Int)Int
Run Code Online (Sandbox Code Playgroud)
有没有办法使用函数值语法执行此操作?忽略隐含片刻,我通常会写出如下的curried函数值:
scala> val sum2 = (a: Int) => (b: Int) => a + b
sum: (Int) => (Int) => Int = <function1>
Run Code Online (Sandbox Code Playgroud)
但是,第二种方法中的函数签名是非常不同的(currying正在明确表达).只是将隐式关键字添加到b中没有多大意义,编译器也会抱怨:
scala> val sum2 = (a: Int) => (implicit b: Int) => a + b
<console>:1: error: '=>' expected but ')' found.
val sum2 = (a: Int) => (implicit b: Int) => a + b
^
Run Code Online (Sandbox Code Playgroud)
此外,从第一种获取函数值的方法中部分应用总和也会导致问题:
scala> val sumFunction = …
Run Code Online (Sandbox Code Playgroud) (.)
采用两个函数,它们接受一个值并返回一个值:
(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)
既然(.)
有两个参数,我觉得(.).(.)
应该是无效的,但它完全没问题:
(.).(.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?我意识到这个问题措辞严厉......所有的功能都只是因为讨论而采取了一个论点.也许更好的方式来说它是类型不匹配.
在C++ 14中,什么是一种理解函数或函数对象的好方法?
特别是,我有一个foo
带有一些随机数量的重载的重载函数:可以通过ADL找到一些重载,其他的可以在无数个地方定义.
我有一个帮助对象:
static struct {
template<class...Args>
auto operator()(Args&&...args)const
-> decltype(foo(std::forward<Args>(args)...))
{ return (foo(std::forward<Args>(args)...));}
} call_foo;
Run Code Online (Sandbox Code Playgroud)
这让我可以将重载集作为单个对象传递.
如果我想要咖喱foo
,我该怎么办呢?
由于curry
和部分功能应用程序经常互换使用,curry
我的意思是,如果foo(a,b,c,d)
是有效的呼叫,那么curry(call_foo)(a)(b)(c)(d)
必须是有效的呼叫.