我试图构建一个接受给定数量参数的函数,并始终返回相同的值。
这是家庭作业的一部分。提供了一个提示:
" k-way T"是一个带有k个参数并且总是返回T的函数.A" 0-way T"只是T。
其中k表示为Church Numeral,T表示True(\ x。\ y.x)的lambda表达式。
完整的任务是提供一个计算k-way OR函数的lambda表达式。其中'布尔数'参数在' boolean'之前提供。参数。 e.g:
((OR 3) F T F)
但是现在我尝试创建 k 参数,并始终返回 T 。 k 作为第一个参数提供。
((TRUE 2) T F) == T
所以基本上我不想创建一个函数,每个教会数字和迭代都有一个参数。
但不知怎的,我完全陷入困境。
我可以只用一个教堂数字吗?或者我需要递归(Y-Combinator)?
一般来说:是否有支持lambda表达式创建的好工具(例如可视化)。
我对lambda演算的力量感到非常惊讶,我真的很想学习它。但我不知道如何......
提前致谢
答案 0 :(得分:4)
我将展示如何实现class ViewController: UITableViewController {
struct Item {
var height: CGFloat = 0
}
var itemDic: [Int: [Item]]!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
itemDic = [0 : [Item(height: 10), Item(height: 30), Item(height: 50), Item(height: 20)],
1 : [Item(height: 20), Item(height: 10)],
2 : [Item(height: 40), Item(height: 30), Item(height: 20), Item(height: 30)]]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return itemDic.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemDic[section]!.count
}
let sectionHeaderHeight: CGFloat = 100
let innerViewOffset: CGFloat = 10
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
// Must > 0
return innerViewOffset
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView(frame: CGRect())
view.backgroundColor = UIColor.blueColor()
let innerView = UIView(frame: CGRect(x: 0, y: innerViewOffset, width: 100, height: 100))
innerView.backgroundColor = colorForSection(section)
view.addSubview(innerView)
return view
}
func colorForSection(section: Int) -> UIColor {
let colors = [UIColor.greenColor(), UIColor.redColor(), UIColor.purpleColor()]
return colors[section]
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let section = indexPath.section
let row = indexPath.row
let items = itemDic[section]!
var height = items[row].height
if (row == items.count - 1) {
var total: CGFloat = 0
for i in items {
total += i.height + 10
}
if(sectionHeaderHeight + 10 > total){
height += (sectionHeaderHeight + 10 - total)
}
}
return height + 10
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")!
return cell
}
}
功能。
由于TRUE
未修复,因此您需要一个定点组合器(k
会这样做,但它不是唯一的定点组合子)。
首先谈谈我在下面使用的符号:Y
(取一个教会数字,检查它是否为教会零并返回教会布尔值),iszero
(教会 - 编码的真值布尔值),T
(教会数字的前身函数)和pred
(定点组合子)。
Y
请注意let TRUE = Y (λr. λn. (iszero n) T (λx. (r (pred n))))
不是lambda演算语法的一部分,它是引入名称的metasyntax(对我们而言)。
此操作如下:let
排序将Y
参数转换为" self" - 当函数调用r
时,它会调用自身。为了说明这一点,我将把上述内容重写为递归形式(警告:它仅用于说明目的,lambda calculus 不允许这个;因为所有函数都是匿名的你不能用他们的名字给他们打电话 - 这是没办法的:)
r
我已经剥离了let TRUE = λn. (iszero n) T (λx. (TRUE (pred n)))
部分并将λr.
替换为r
(再次,请不要在作业中执行此操作,这不是有效的lambda演算)。
这个定义更容易理解:如果像TRUE
那样调用TRUE
,它只返回TRUE 0
,否则它返回一个包含函数的参数的函数( n - 1)参数,基本上代表n个参数的函数。
至于你关于工具的问题:一种方法是使用Scheme / Racket - 这将有助于检查你的" lambda演算代码"按计划运行。例如,以下是Racket中T
的实现:
TRUE
我应该补充一点,我在这里使用内置的布尔值,整数,if-expression,(define (Y f)
((lambda (x) (x x))
(lambda (x) (lambda (a) ((f (x x)) a)))))
(define TRUE
(Y (lambda (r)
(lambda (n)
(if (zero? n)
#t
(lambda (x) (r (sub1 n))))))))
;; tests
> (TRUE 0)
#t
> ((TRUE 1) #f)
#t
> (((TRUE 2) #f) #f)
#t
> ((((((TRUE 5) #f) #f) #f) #f) #f)
#t
,sub1
而不是Church编码的。否则会使这个例子变得更大(或不完整)。
答案 1 :(得分:0)
我现在也正在做确切的作业,我只是想告诉您和任何未来的读者,绝对不需要定点组合器。
要从对Pk:=(k-way T, k-way OR)
到对Pk+1:=(k+1-way T, k+1-way OR
,只需应用函数lambda Pk. (lambda a b c. c a b) (lambda arg. Pk (lambda x y. x)) (lambda arg. Pk arg)
。
k+1-way OR
,新的k-way OR
就是Pk
中的F
;如果参数为k-way T
,则新T
。
现在有了此功能,您唯一需要做的就是将其n次应用于起始对P0:=(lambda a b c. c a b) (lambda x y. x) (lambda x y. y)
,您可以使用教堂数字n来进行此操作。最后,您只需要使用该对的第二部分,就应该剩下一个n-way OR
。