如何编译和运行此代码?如何转换为原始递归?

时间:2014-11-17 15:16:43

标签: haskell

以下代码应返回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大小写和非零大小写。我想也许我可以将它应用于每个案例,但我不确定这是否可行。

3 个答案:

答案 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>是使用xy的表达式。所有上述行在Haskell中都是等效的。

答案 2 :(得分:1)

如果您查看compilePoly的类型签名,它是Poly -> (Int -> Int) - 您需要传递Int才能获得结果,例如compilePoly (PAdd PVar PVar) 0