首页 > 解决方案 > Haskell 评估

问题描述

我有以下代码块:

data G = F G G | H Int deriving (Show, Eq)

example :: Int -> G -> G
example 0 (H i) = (H i)
example n (H i) = F (example (n-1) (H i)) (example (n-1) (H i))
example n (F i1 i2) = F (example n i1) (example n i2)

当我运行example 0 (F (H 1) (H 2))时,它按预期返回F (H 1) (H 2)

当我运行时example 1 (F (H 1) (H 2)),它会返回F (F (H 1) (H 1)) (F (H 2) (H 2))

这不是我想要的。我需要返回F (F (H 1) (H 1)) (H 2)

我的意思是在第 6 行example n (F i1 i2) = F (example n i1) (example n i2),我调用了递归函数两次。但是我希望在我们评估之前先(example n i1)评估并更新变量n(example n i2)

对此确切问题的任何帮助/解决方案将不胜感激。我已经尝试了几个小时,但成功率为零。

标签: haskellfunctional-programming

解决方案


问题似乎是您想使用example'update' n。但是,您不能直接这样做,因为example返回一个G值,并且n是一个Int.

那么,您似乎需要一个函数G -> Int。问题是没有明确正确的方法来编写该函数。事实上,有无数种可能的实现方式。这是一个示例:

evalZero :: G -> Int
evalZero = const 0

evalOne :: G -> Int
evalOne = const 1

evalLeft :: G -> Int
evalLeft (H i) = i
evalLeft (F g _) = evalLeft g

evalRight :: G -> Int
evalRight (H i) = i
evalRight (F _ g) = evalRight g

evalSum :: G -> Int
evalSum (H i) = i
evalSum (F g1 g2) = evalSum g1 + evalSum g2

evalProduct :: G -> Int
evalProduct (H i) = i
evalProduct (F g1 g2) = evalProduct g1 * evalProduct g2

evalPlusOneProduct :: G -> Int
evalPlusOneProduct (H i) = i + 1
evalPlusOneProduct (F g1 g2) = evalPlusOneProduct g1 * evalPlusOneProduct g2

-- etc.

如图evalPlusOneProduct所示,您可以任意添加或减去一个常量Int,或者就此而言,乘以一个常量,或者执行更复杂的任意计算。因为有无限多的整数,所以有无限多的实现(虽然,从技术上讲,我们受到范围的限制Int)。

一旦你弄清楚如何转换GInt,就可以使用该函数从左值和左值计算n1nG


推荐阅读