功能定义:
first_threes :: [Int] -- first three numbers repeated
first_threes = 1:2:3:first_threes -- th.1
take :: Int -> [a] -> [a] -- take
take 0 _ = [] -- t.1
take n (x:xs) = x : (take (n - 1) xs) -- t.2
sum :: [Int] -> Int -- summation of an Int list
sum [] = 0 -- s.1
sum (x:xs) = x + (sum xs) -- s.2
我需要使用上面函数的定义来重写下面的语句。我需要得到答案9.我需要使用“懒惰评估”证明每个解决方案的合理性。
Hugs_Main> my sum (my take 5 first_threes)
9
我正在努力找出20个解决方案,获得9个答案。以下是我的前10个解决方案,但我想不出别的。任何人都可以帮忙吗?
我的前10个解决方案:
my_sum (my_take 5 first_threes)
my_sum (my_take 5 (1:2:3:first_threes))
my_sum (my_take 5 (1:2:first_threes))
my_sum (my_take 5 (2:first_threes))
my_sum (my_take 4 (3:first_threes))
my_sum (1:2:3:(my_take 2 (first_threes)))
my_sum (1:2:(my_take 3 (first_threes)))
my_sum (1:(2:my_take 3 (3:first_threes)))
my_sum (1:(my_take 4 (2:3:first_threes)))
my_sum (1:(my_take 4 (2:first_threes)))
答案 0 :(得分:1)
我认为这开始了老师想要看到的内容
my_sum (my_take 5 first_threes)
-- th.1
my_sum (my_take 5 (1:2:3:first_threes))
-- t.2
my_sum (1 : my_take 4 (2:3:first_threes))
-- s.2
1 + my_sum (my_take 4 (2:3:first_threes))
-- continue yourself
关于术语的说法:检查是否必须使用解决方案。我给了你一些重写。在每一步中,您都使用其中一个等于重写您的术语。评论指出我用于重写的内容..
答案 1 :(得分:0)
-- original expression
sum (take 5 first_threes)
-- (substitution) apply `take 5 first_threes` to `sum`
case take 5 first_threes of
[] -> 0
(x : xs) -> x + sum xs
-- pattern matching force evaluation of the first cons constructor so
-- we need eval `take 5 first_threes` first
-- apply `first_threes` to `take n` (substitution)
(\ n -> case n of
0 -> []
_ -> case first_trees of
_ -> []
(x : xs) -> x : take (n - 1) xs) 5
-- apply 5 to the lambda (substitution)
case 5 of
0 -> []
_ -> case first_trees of
_ -> []
(x : xs) -> x : take (5 - 1) xs
-- 5 is already in normal form, after case analysis we will have
case first_trees of
_ -> []
(x : xs) -> x : take (5 - 1) xs
-- pattern matching again (see above)
case 1 : 2 : 3 : first_threes of
_ -> []
(x : xs) -> x : take (5 - 1) xs
-- after case analysis (?) we will have
1 : take (5 - 1) (2 : 3 : first_threes)
-- now we return back to our original expression
case 1 : take (5 - 1) (2 : 3 : first_threes) of
[] -> 0
(x : xs) -> x + sum xs
-- after case analysis we will have
1 + sum (take (5 - 1) (2 : 3 : first_threes))
-- (+) operator is strict in both args
-- the first arg is already evaluated, but we also need to evaluate the second
1 + case take (5 - 1) (2 : 3 : first_threes) of
[] -> 0
(x : xs) -> x + sum xs
-- and so on...
-- in the end we will get
1 + (2 + (3 + (1 + (2 + (0)))))
-- which is evaluated in reverse order (starting from the `0`)