以下代码应返回Poly表达式的表示。例如(\ x - > x + x)将是表达式的返回表示(PAdd PVar PVar)。我自己没有写过这段代码,所以我不知道如何运行它。
data Poly = PConst Int |
PVar |
PAdd Poly Poly |
PMul Poly Poly
compilePoly :: Poly -> (Int -> Int)
compilePoly (PConst x) = (\_ -> x)
compilePoly (PVar) = id
compilePoly (PAdd p1 p2) = (\x -> (compilePoly p1 x) + (compilePoly p2 x))
compilePoly (PMul p1 p2) = (\x -> (compilePoly p1 x) * (compilePoly p2 x))
我尝试像这样(以及其他几种方式)运行它,但它从不编译。
main = do
print $ compilePoly $ PAdd PVar PVar
我还需要知道如何将其转换为原始递归。我想不出这样的方式。 Poly的数据类型有4个案例,它们都需要解决。原始递归需要0大小写和非零大小写。我想也许我可以将它应用于每个案例,但我不确定这是否可行。
答案 0 :(得分:2)
compilePoly
获取Poly
并返回函数。您无法打印功能。你可以执行它们:
main = do
let f = compilePoly $ PAdd PVar PVar
print (f 17)
答案 1 :(得分:1)
您需要为其提供输入。值。您有compilePoly (PAdd PVar PVar) :: Int -> Int
,但无法打印。相反,尝试
main = print $ compilePoly (PAdd PVar PVar) 1
这相当于(\x -> x + x) 1
,结果为2
。
可能会更清楚地说明compilePoly
的定义有点不同:
compilePoly :: Poly -> Int -> Int
compilePoly (PConst c) x = c
compilePoly (PVar) x = x
compilePoly (PAdd p1 p2) x = compilePoly p1 x + compilePoly p2 x
compilePoly (PMul p1 p2) x = compilePoly p1 x * compilePoly p2 x
现在显而易见的是compilePoly
实际上需要2个参数,其中第二个是变量的值。我在这里所做的就是将\x ->
移到=
符号的左侧(并将(PConst x)
重命名为(PConst c)
)。您始终可以进行以下转换
f = \x y -> <something x y>
f = \x -> \y -> <something x y>
f x = \y -> <something x y>
f x y = <something x y>
其中<something x y>
是使用x
和y
的表达式。所有上述行在Haskell中都是等效的。
答案 2 :(得分:1)
如果您查看compilePoly
的类型签名,它是Poly -> (Int -> Int)
- 您需要传递Int
才能获得结果,例如compilePoly (PAdd PVar PVar) 0