【发布时间】:2016-05-01 14:14:45
【问题描述】:
我对 Haskell 还是很陌生,我正在尝试解决一个问题。我尝试了一些东西,但我很确定这是错误的。
问题:
foldr : f x NIL = x
foldr : f x (cons a list) = f a (foldr f x list)
让我们玩得开心,并结合多种不同语言的功能。
(1)借用课程笔记和Haskell,我们定义一个函数foldl,
(a)foldl f x NIL = x
(b)foldl f x (cons a list) = foldl f (f x a) list
(2) 借用 Python,我们可以将字符串视为字符的序列(即列表),
“bar” ≡ (‘b’ ‘a’ ‘r’) ≡ [‘b’, ‘a’, ‘r’]
(3) 借用 Lisp,我们可以使用 cons 单元格来表示或创建列表,
(‘b’ ‘a’ ‘r’) ≡ (cons ‘b’ (cons ‘a’ (cons ‘r’ nil)))
(4) 借用Fortran,我们可以定义一个字符串连接函数, //,
‘concate’//’nation’ ⇒‘concatenation’
(5) 借用Scheme,定义一个toggle函数,
f x y = f y x,
(define toggle (lambda (f x y) (f y x)))
也就是说,toggle 函数切换了它的参数,在 Lambda Calculus 中是,
|_f. |_x. |_y. f y x
因此,例如,
(f ‘back’ ‘drop’) ⇒(f ‘drop’ back’)
在本题中,请追踪以下函数的执行/缩减:
foldl (toggle //) nil (“foo” “bar” “baz”)
以下是给我的提示:
foldl (toggle //) nil (“foo” “bar” “baz”)
Step1:从 (1b) 开始,左侧,foldl f x (cons a list)
with f = (toggle //), x = nil, and list = (“foo” “bar” “baz”)
Step2:使用(3)递归展开列表
Step3:使用(1b),右侧,foldl f(f x a)列表
to recursively apply f, (toggle //), to the expanded list
Step4:使用 (5) 在列表表达式中应用切换函数。
Step5: 使用 (4), //, 减少表达式
我得到了什么:
foldl (toggle //) nil (“foo” “bar” “baz”)
foldl f x (cons a list) – via (1b)
foldl f x(a list) – via (3)
foldl f (f x a) list – via (1b)
foldl (toggle //) (toggle // x a) list – via(5)
foldl x // // a list – via (4)
foldl nil a (“foo” “bar” “baz”)
我知道这不可能,但我觉得我就在附近。如果我能得到一些指导,我觉得我可以摆脱困境并成功理解。
【问题讨论】:
-
在解决问题时坚持使用 Haskell 的语法(方程式,
[...],...);这是最清楚的。然后当你完成后,将结果转换回你所期望的任何疯狂的符号组合。
标签: haskell lambda fold reduction