public static <T, U, R> Function<U, R> partial(BiFunction<T, U, R> f, T x) {
return (y) -> f.apply(x, y);
}
Run Code Online (Sandbox Code Playgroud)
在上面的表达式中,我可以理解函数partial返回另一个函数,Function<U, R>。它Function<U, R>本身返回一个 R 值。其余的static <T, U, R>代表什么?我的意思是如果Function<U, R>返回一个 R 是怎么回事<T, U, R>?
我在部分函数应用程序的语法方面遇到问题。以下代码工作正常,并输出:two-three-four
import kotlin.coroutines.experimental.*
inline fun <T> Iterable<T>.forEachFrom(beg:Int, act:(T)->Unit) {
var i=0; if (beg>=0) for (e in this) if (i++ >= beg) act(e)
} // sample function I am testing; please don't change this!
fun main(a:Array<String>) {
val l = listOf("zero", "one", "two", "three", "four")
fun test() = buildSequence { l.forEachFrom(2) { yield(it) } }.joinToString("-")
println(test())
}
Run Code Online (Sandbox Code Playgroud)
我想封装我的test(),所以它被称为:
test(l.forEachFrom(2)) 但是,我似乎无法正确获取类型/语法。
我将如何重写test()函数定义以使其成为可能?
在F#中如果我接受一个带有两个参数的函数,例如,mod(%):
13 % 10
// val it : int = 3
Run Code Online (Sandbox Code Playgroud)
这是一样的
(%) 13 10
// val it : int = 3
Run Code Online (Sandbox Code Playgroud)
是否有任何方法可以用管道符号写出来,把13?
显然,"双参数函数"实际上是一个返回中间函数的单参数函数.管道也可以
10 |> (%) 13
// val it : int = 3
Run Code Online (Sandbox Code Playgroud)
但是,我需要另一种方法,即管道第一个参数13,第二个参数10部分应用,但不是第一个参数.
语言中是否有任何有助于这样做的东西,而不是每次都创建额外的lambdas,即避免以下情况?
13 |> (fun x -> x % 10)
Run Code Online (Sandbox Code Playgroud) 我正在寻找一种在 python 中部分应用函数的方法,该方法易于理解、可读、可重用,并且尽可能少地容易出现编码错误。最重要的是,我希望该样式尽可能具有高性能 - 堆栈上的帧越少越好,部分应用的函数的内存占用也越少越好。我考虑了 4 种风格并写了下面的例子:
import functools
def multiplier(m):
def inner(x):
return m * x
return inner
def divide(n,d):
return n/d
def divider(d):
return functools.partial(divide,d=d)
times2 = multiplier(2)
print(times2(3)) # 6
by2 = divider(2)
print(by2(6)) # 3.0
by3 = functools.partial(divide,d=3)
print(by3(9)) # 3.0
by4 = lambda n: divide(n,4)
print(by4(12)) # 3.0
Run Code Online (Sandbox Code Playgroud)
我对他们的分析是:
times2是一个嵌套的东西。我猜想 python 用边界做了一个闭包m,一切都很好。该代码是可读的(我认为)并且易于理解。没有外部库。这就是我今天使用的风格。
by2有一个明确的命名函数,这对用户来说很简单。它使用 functools,因此它为您提供了额外的导入。我在某种程度上喜欢这种风格,因为它是透明的,如果我愿意的话,我可以选择divide以其他方式使用。将此与inner不可到达的进行对比。
by3就像by2,但是迫使代码的读者感到舒服,functools.partial因为他们就在眼前。我不太喜欢的是 PyCharm 无法为我的工具提示提供参数应该functools.partial是什么,因为它们实际上是by3 …
我想基于布尔值(其中一个参数)以不同的方式应用3参数函数.
我希望能够以中缀的方式应用它,以便我可以链接它(例如下面的例子).类似下面的东西但实际上有效.
f :: Bool -> a -> a -> a
f True i j = i
f False i j = j
... y `(f True)` z `(f False)` b
Run Code Online (Sandbox Code Playgroud)
我需要将Bool作为第二个变量吗?或者是其他东西?我有点迷茫.
PS我想要这样做的原因是有可选的追加功能
我正在学习一些函数式编程语言,学习感兴趣的东西,现在我正在研究Scala.我想要做的是弄清楚编写一个函数的最简单方法,该函数调用double一个参数并将其加倍.到目前为止我想出的是:
def double = (x:Int) => x*2
Run Code Online (Sandbox Code Playgroud)
要么
def double(x:Int) = x*2
Run Code Online (Sandbox Code Playgroud)
这有效,但我正在寻找最简单的方法.在Haskell中,我可以简单地这样做:
double = (*2)
Run Code Online (Sandbox Code Playgroud)
因为它是部分应用的函数,所以不需要命名变量或指定任何类型(我确信*函数会处理它).使用Scala有类似的方法吗?我尝试了一些,特别是使用_而不是x,但似乎没有工作.
我不明白为什么以下练习在第一原理的Haskell编程中 "有效" :
type Subject = String
type Verb = String
type Object = String
data Sentence =
Sentence Subject Verb Object
deriving (Eq, Show)
s1 = Sentence "dogs" "drool"
s2 = Sentence "Julie" "loves" "dogs"
Run Code Online (Sandbox Code Playgroud)
将其加载到ghci中表明它可以很好地解决问题,但为什么定义s1甚至有意义呢?我仍然是Haskell的新手,所以起初我认为这是因为在s1Haskell中隐含地让Object字符串为空.但是之后...
*Main> s1
<interactive>:13:1:
No instance for (Show (Object -> Sentence))
arising from a use of `print'
Possible fix:
add an instance declaration for (Show (Object -> Sentence))
In a stmt of an interactive GHCi command: print …Run Code Online (Sandbox Code Playgroud) 我是Haskell的新手,看一个使用函数应用程序的简单例子$.
它似乎很简单 - 它需要一个函数并将其应用于一个值.
所以这是有道理的:
> (+3) $ 2
5
Run Code Online (Sandbox Code Playgroud)
这也是有道理的:
> ($) (+3) 2
5
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为第一个参数是函数,第二个参数是值.
现在考虑使用$创建部分功能.
查看类型,这是有道理的 - 它只需要一个Num类型值b:
> :t ($) (+3)
($) (+3) :: Num b => b -> b
Run Code Online (Sandbox Code Playgroud)
但是这里我迷路了 - 这里发生了什么?:
> :t ($) (2)
($) (2) :: Num (a -> b) => a -> b
Run Code Online (Sandbox Code Playgroud)
我原以为第一个参数需要是一个函数,而不是一个简单的Num值.
所以这是我的问题:
Num (a -> b)语法是什么意思?($)以这种方式使用的例子是什么($) (2)?谢谢!
polymorphism haskell types partial-application parametric-polymorphism
在Learn you a Haskell 中,给出了以下示例:
map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
Run Code Online (Sandbox Code Playgroud)
但是,我不明白为什么会这样。
函数的签名是
Prelude> :info ($)
($) :: (a -> b) -> a -> b
Prelude> :t ($ 3)
($ 3) :: Num a => (a -> b) -> b
Run Code Online (Sandbox Code Playgroud)
然而,->是一个左结合运营商,所以$ :: (a -> b) -> a -> b实际上((($ :: (a-b))-> a)-> b),所以不宜3在($ 3)对应(a->b)的功能是函数的第一个“变量” $?即为什么是($ 3)签名的函数(a -> b) -> b …
作为问题的一个例子,有没有办法partialconcat在下面的代码中实现宏?
#define apply(f, x) f(x)
apply(partialconcat(he),llo) //should produce hello
Run Code Online (Sandbox Code Playgroud)
编辑:
这是另一个例子,给定一个FOR_EACH可变参数宏(参见另一个问题的答案中的示例实现).
假设我想在几个对象上调用一个成员,可能在另一个宏中用于更大的目的.我想要一个宏callAmber,其行为如下:
FOR_EACH(callMember(someMemberFunction), a, b, c);
Run Code Online (Sandbox Code Playgroud)
产生
a.someMemberFunction(); b.someMemberFunction(); c.someMemberFunction();
Run Code Online (Sandbox Code Playgroud)
这需要callMember(someMember)产生一个行为像的宏
#define callMember_someMember(o) o.someMember()
Run Code Online (Sandbox Code Playgroud)