标签: currying

Clojure中的高阶函数

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功能,我正在谈论更高层次的抽象.是否有任何惯用模式可供遵循?有些宏?是定义宏的最佳方式还是有替代解决方案?

clojure currying higher-order-functions

36
推荐指数
2
解决办法
1万
查看次数

在scala中使用FoldRight的FoldLeft

在Scala中进行功能编程时,我遇到了这个问题:

你可以在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

34
推荐指数
3
解决办法
5877
查看次数

适当的C#中的Currying

给定一个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)

c# lambda currying

33
推荐指数
1
解决办法
2万
查看次数

用Mathematica卷曲

可以使用以下结构在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吗?

wolfram-mathematica currying

32
推荐指数
5
解决办法
4019
查看次数

Haskell Monad绑定运算符混淆

好吧,所以我不是Haskell程序员,但我对Haskell背后的许多想法非常感兴趣,并且我正在研究它.但是我被困在第一个方面:我似乎无法绕过Monads,这似乎是相当基础的.我知道有一百万个关于SO的问题要求解释Monads,所以我会更加具体地说明了什么在困扰我:

我读了这篇优秀的文章(Javascript中的介绍),并认为我完全了解Monads.然后我读了Monads上的维基百科条目,看到了:

多态类型(M t)→(t→M u)→(M u)的绑定操作,其中Haskell由中缀运算符表示>> =.它的第一个参数是monadic类型的值,它的第二个参数是一个函数,它从第一个参数的基础类型映射到另一个monadic类型,其结果是在其他monadic类型中.

好的,在我引用的文章中,bind是一个仅占用一个参数的函数.维基百科说两个.我认为我对Monads的理解如下:

  1. Monad的目的是使用具有不同输入和输出类型的函数并使其可组合.它通过使用单个monadic类型包装输入和输出类型来实现此目的.
  2. Monad由两个相互关联的函数组成:bind和unit.绑定采用不可组合的函数f并返回一个新函数g,它接受monadic类型作为输入并返回monadic类型.g是可组合的.unit函数接受f期望的类型的参数,并将其包装在monadic类型中.然后可以将其传递给g,或者传递给g之类的任何函数组合.

但是肯定有一些错误,因为我的bind概念需要一个参数:一个函数.但是(根据维基百科)Haskell的绑定实际上有两个参数!我的错误在哪里?

monads haskell currying composition function-composition

32
推荐指数
3
解决办法
1万
查看次数

实际使用咖喱功能?

有很多关于如何理解函数的教程,以及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)

我只能看到更多的代码,没有更多的灵活性......

lisp scheme haskell functional-programming currying

29
推荐指数
2
解决办法
4598
查看次数

Variadic curried sum函数

我需要一个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).
有关如何做到这一点的任何想法?

javascript currying

27
推荐指数
7
解决办法
4万
查看次数

含有隐含的Scala函数文字

请原谅我,如果已经在别处问过这个问题.我有一个涉及函数值和隐式参数的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)

scala function implicit currying literals

25
推荐指数
3
解决办法
4667
查看次数

组成功能组合:(.).(.)如何工作?

(.)采用两个函数,它们接受一个值并返回一个值:

(.) :: (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)

这里发生了什么?我意识到这个问题措辞严厉......所有的功能都只是因为讨论而采取了一个论点.也许更好的方式来说它是类型不匹配.

haskell currying pointfree

25
推荐指数
4
解决办法
1934
查看次数

我该如何制作咖喱功能?

在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)必须是有效的呼叫.

c++ templates overloading currying c++14

25
推荐指数
2
解决办法
3458
查看次数