函数可以是高度嵌套的结构:
function a(x) {
return b(c(x), d(e(f(x), g())))
}
首先,想知道一个函数是否具有 instance 。即,功能的评估是功能的实例。从这个意义上说,类型是函数,实例是它的评估。如果可以,那么如何将函数建模为类型(使用面向类型理论的语言,例如Haskell或Coq)。
几乎就像:
type a {
field: x
constructor b {
constructor c {
parameter: x
},
...
}
}
但是我不确定我走的路是否正确。我知道您可以说一个函数具有[返回]类型。但是我想知道一个函数是否可以被视为类型,如果可以的话,如何在面向类型理论的语言中将其建模为类型,并在该模型中对函数的实际实现进行建模。
答案 0 :(得分:3)
我认为问题在于,直接基于实现的类型(我们称它们为“ i-types”)似乎不是很有用,我们已经有了建模它们的好方法(称为“程序”-哈哈)。
在您的特定示例中,函数的完整i型,即:
add $t0,$t1,$t2
beqz $t0, next
b next2
addi $t0,$t0,2
next:
addi $t2,$t0,3
next2:
addi $t1,$t1,2
只是实现本身的冗长替代语法。也就是说,我们可以使用类似Haskell的语法将这种i类型编写为:
type a {
field: x
constructor b {
constructor c {
parameter: x
},
constructor d {
constructor e {
constructor f {
parameter: x
}
constructor g {
}
}
}
}
另一方面,我们可以将您的函数实现直接转换为Haskell术语级语法,以将其编写为:
itype a :: a x = b (c x) (d (e (f x) g))
i型和实现完全相同。
您将如何使用这些i型?编译器可以通过派生参数和返回类型来对程序进行类型检查来使用它们。 (幸运的是,有一些著名的算法,例如Algorithm W,用于同时从此类i-types派生和类型检查参数以及返回类型。)程序员可能不会直接使用i-types。太复杂了,无法用于重构或推理程序行为。他们可能想要查看编译器派生的类型作为参数并返回类型。
尤其是,在Haskell的类型级别上对这些i型进行“建模”似乎没有效果。 Haskell已经可以在术语级别对其进行建模。只需将您的i型代码编写为Haskell程序即可:
a x = b (c x) (d (e (f x) g))
并且不要运行它。恭喜,您已经成功为这些i型建模!您甚至可以使用GHCi查询派生参数和返回类型:
a x = b (c x) (d (e (f x) g))
b s t = sqrt $ fromIntegral $ length (s ++ t)
c = show
d = reverse
e c ds = show (sum ds + fromIntegral (ord c))
f n = if even n then 'E' else 'O'
g = [1.5..5.5]
现在,您可能正在想象某些情况下实现和i-type可能会有所不同,也许是当您开始引入文字值时。例如,也许您觉得上面的函数> :t a
a :: Floating a => Integer -> a -- "a" takes an Integer and returns a float
>
:
f
应该为分配类似以下类型的类型,该类型不取决于特定的文字值:
f n = if even n then 'E' else 'O'
不过,最好还是定义一个任意术语级别type f {
field: n
if_then_else {
constructor even { -- predicate
parameter: n
}
literal Char -- then-branch
literal Char -- else-branch
}
,例如:
Char
并在词级上对此i型进行建模:
someChar :: Char
someChar = undefined
同样,只要您不运行程序,就已经成功建模了f n = if even n then someChar else someChar
的i型,可以查询其参数并返回类型,并将其作为更大程序的一部分进行类型检查。等
答案 1 :(得分:2)
我不清楚您的目标是什么,所以我将尝试指出一些您可能想阅读的相关术语。
一个函数不仅具有返回类型,而且还具有描述其参数的类型。因此f
的(Haskell)类型显示为“ f接受一个Int和一个Float,并返回一个Float列表。”
f :: Int -> Float -> [Float]
f i x = replicate i x
类型还可以描述函数的更多说明。在这里,我们可能希望类型说明以下内容:列表的长度将与第一个参数相同,或者列表的每个元素将与第二个参数相同。长度索引列表(通常称为向量)是依赖类型的常见第一个示例。
您可能还对将类型作为参数并返回类型的函数感兴趣。这些有时称为“类型级函数”。在Coq或Idris中,可以使用与更熟悉的函数相同的方式来定义它们。在Haskell中,我们通常使用Type Families或Functional Dependencies使用类型类来实现它们。
回到问题的第一部分,Beta Reduction是为函数的每个参数填充具体值的过程。我听说有人将表达式描述为“减少后”或“完全减少”,以强调此过程中的某个阶段。这类似于“呼叫站点”功能,但强调表达式和参数,而不是周围的上下文。