高阶函数中的类型定义和类型不匹配

责备

我目前正在研究Martin Odersky的Coursera课程的视频讲座,即Scala中的Functional Programming Principles。在第2.1课中,他演示了使用基函数构成高阶函数的过程sum()他实现了无尾递归的阶乘,但我还是尝试了尾递归,因为它仍然只是一行代码。结果,我认为Odersky没有类型不匹配。在定义中sum(),参数f取一个,Int然后返回一个Int我知道我可以通过调整我的function *来解决这个问题,但这让我想知道一般如何设计高阶函数。有没有一种方法可以调整或规避此类型定义,以允许使用灵活数量的参数的函数?有人给我看过一点Haskell,我想知道Scala的函数参数是否可以以类似的松散方式键入……或者也许还有另一种解决方案更原始于Scala。请假设我昨天才刚开始与Scala一起玩,并且在您的解释中对计算机科学的知识有限,因为确实如此。

def sum(f: Int => Int, a: Int, b: Int): Int =
    if (a > b) 0 else f(a) + sum(f, a+1, b) 


//Factorial with tail recursion.  The one in the lesson DOES NOT use tail recursion.
//prev is an accumulator.
def fact(a: Int, prev:Int = 1): Int =
        if (a == 0) prev else fact(a-1, a * prev)


def sumFactorials(a: Int, b: Int): Int = sum(fact, a, b)

*我知道我可以通过将当前内容嵌套fact()在另一个函数中来解决此问题,如下所示:

def factorial(a: Int): Int ={
    def fact(n: Int, prev:Int = 1): Int =
            if (n == 0) prev else fact(n-1, n * prev)
    fact(a)
}

从我之前在Haskell的经验中得出的印象是,函数式编程仅使用一个参数就可以促进函数化,从而促进了函数的使用。无论如何,这与实际问题有些关系,但是如果我只是以问题的精神来疯狂屠杀FP,请随时在评论中解决此问题。

马特·马龙

我认为这里发生了几件事。

首先,我认为您无法处理事实函数(使用具有默认值的函数,就好像其类型实际上少了一个参数)是不可能的。即使第二个Int默认为1,一个(Int,Int)=> Int仍然是(Int,Int)=> Int。您不能将其作为Int => Int传递。不过,我可以看到您可能会想到的地方。

其次,事实和阶乘函数不相等。不管递归多少次,阶乘函数都会反复使用'a'的原始值。事实函数在每个调用中使用减量“ a”。

根据您的“固定”阶乘函数,该函数有效地采用了三个参数:原始a,减n和乘以prev。以下代码是等效的。

def sum(f: (Int,Int,Int) => Int, a: Int, b: Int): Int = 
    if (a > b) 0 else f(a,a,1) + sum(f, a+1, b) 

def fact(a: Int, n: Int, prev:Int): Int = 
    if (n == 0) prev else fact(a, n-1, a * prev)

def sumFactorials(a: Int, b: Int): Int = sum(fact, a, b)

您也不能将sum编写为:

def sum(f: (Int, Int) => Int, a: Int, b: Int): Int =
    if (a > b) 0 else f(a) + sum(f, a+1, b) 

传入的函数f可能具有默认参数,但可能没有默认参数,因此编译器允许f(a)调用并不安全。

我认为默认参数的实现更像是“语法糖”,就像他们所说的那样,附加在实际函数上,而不是像函数currying那样。您可以使用currying进行此操作,但是必须显式声明curried函数。假设您要使用事实逻辑(而不是阶乘逻辑),可以这样做:

def sum(f: Int => Int, a: Int, b: Int): Int =
    if (a > b) 0 else f(a) + sum(f, a+1, b) 

def fact(prev:Int = 1)(a: Int): Int =
        if (a == 0) prev else fact(a * prev)(a-1)

def sumFactorials(a: Int, b: Int): Int = sum(fact(1), a, b)

请注意,我们必须切换事实参数的位置。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Kotlin - 高阶函数和类型不匹配

来自分类Dev

函数类型与函数定义不匹配

来自分类Dev

通用高阶函数的不兼容流类型

来自分类Dev

Haskell函数中的类型不匹配

来自分类Dev

Scala 中的类型不匹配(hasNext 函数)

来自分类Dev

map函数中的Scala类型不匹配

来自分类Dev

使用 simulacrum 的类型类定义中的类型不匹配

来自分类Dev

函数声明和定义的返回类型不匹配,尽管编译器还可以吗?

来自分类Dev

Haskell高阶函数类型

来自分类Dev

reasonml类型高阶函数

来自分类Dev

错误#7977:函数引用与其定义之间的类型不匹配

来自分类Dev

无法在oracle中创建表函数,在FETCH游标和INTO变量之间发现类型不匹配

来自分类Dev

递归函数,如果Rust中的语句类型不匹配

来自分类Dev

Fortran 95中的“错误:函数的返回类型不匹配”

来自分类Dev

flatMap函数中的Apache Flink流类型不匹配

来自分类Dev

错误:声明要返回的函数中的返回类型不匹配

来自分类Dev

Access中的DLookup函数返回类型不匹配错误

来自分类Dev

Fortran 95中的“错误:函数的返回类型不匹配”

来自分类Dev

在QTP中调用函数时类型不匹配

来自分类Dev

错误:声明要返回的函数中的返回类型不匹配

来自分类Dev

数据类型在函数调用中不匹配

来自分类Dev

使用Java的RDD函数中的类型不匹配

来自分类Dev

pytorch中的类型不匹配

来自分类Dev

数组中的类型不匹配

来自分类Dev

flexboxlayout 中的类型不匹配

来自分类Dev

Typescript推断高阶函数中内部函数的类型

来自分类Dev

高阶函数,流类型注释

来自分类Dev

高阶函数的Clojure类型提示

来自分类Dev

高阶函数参数类型的类型推断错误

Related 相关文章

热门标签

归档