简体   繁体   English

在Scala中使用3个函数进行咖喱

[英]Currying with 3 functions in Scala

Im trying to write a function using currying to compute a Collatz series... But im getting lost when trying to write the parameters for construct6(...) 我正在尝试使用currying编写函数来计算Collat​​z级数...但是我在尝试为construct6(...)编写参数时迷失了方向

def c: Int => Int = construct6(isEven)(dec, inc)

//DONT KNOW WHAT TO DO HERE
def construct6: ((Int => Boolean) => (Int => Int, Int => Int)) => (i => (e, o)) = { 
    if (i(n)) e(n) else o(n)
}

def isEven: (Int) => (Boolean) = (a) => (a % 2 == 0)
def dec: (Int) => (Int) = (a) => (a / 2)
def inc: (Int) => (Int) = (a) => (a * 3 + 1)

You're construct6 function MUST take a Int n. 您正在构造函数必须带一个Int n。 Here is the function curried 3 times... 这是函数3次咖喱...

def construct6(i: Int => Boolean)(e: Int => Int, o: Int => Int)( n: Int): Int = 
    if (i(n)) e(n) else o(n)

When dealing with problems like this it is always important to look at the type signatures and see that they match up. 处理此类问题时,查看类型签名并确保它们匹配非常重要。 Notice that construct6 MUST return an Int. 注意,construct6必须返回一个Int。 We can doing some functional magic to make a function with a type signature to match Int => Int by doing this: 通过执行以下操作,我们可以做一些功能魔术,以使具有类型签名的函数与Int => Int匹配:

val c: Int => Int = construct6(isEven)(dec, inc)(_: Int)

We are partially applying the function you want for i, e, o, and leaving n as a variable. 我们将部分地为i,e,o应用所需的函数,并将n保留为变量。

Given: 鉴于:

def isEven: (Int) => (Boolean) = (a) => (a % 2 == 0)
def dec: (Int) => (Int) = (a) => (a / 2)
def inc: (Int) => (Int) = (a) => (a * 3 + 1)

you are still missing the n parameter to construct6 (as Andrew Cassidy says). 您仍然缺少Construct6的n参数(如Andrew Cassidy所说)。 Since you need to curry its parameters, it's more readable if you define construct6 like this (but it's basically the same definition you gave, I just added the n:Int at the end): 由于您需要处理其参数,因此,如果您这样定义construct6,则可读性更好(但它基本上与您给出的定义相同,我在末尾添加了n:Int):

def construct6 (i:Int => Boolean)(e:(Int => Int)) (o:(Int => Int))(n:Int)
 = if (i(n)) e(n) else o(n)

you can now define c as a Int=>Int by leaving out the last parameter n to construct6. 您现在可以通过将最后一个参数n遗漏到Construct6上,将c定义为Int=>Int In the REPL: 在REPL中:

scala> def c: Int => Int = construct6(isEven)(dec)(inc)
c: Int => Int

scala> c(8)
res0: Int = 4

which I believe is what you were trying to do. 我相信这就是您要尝试做的。

If you want to infer c's type instead of specifying it as a Int => Int explicitly) you will have to use the omnipresent _ to confirm to Scala that you're not just leaving out anything by mistake: 如果要推断c的类型而不是将c的类型明确指定为Int => Int ),则必须使用无所不在的_来向Scala确认您不只是错误地遗漏了任何内容:

scala> def c2= construct6(isEven)(dec)(inc) _
c2: Int => Int

scala> c2(8)
res1: Int = 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM