1

假设我们有一个这样的函数:

f:Int->Int

这为我们提供了基于输入的修改后的输出。

我的问题是,无论如何我可以编写这个函数,以便不对输入进行评估吗?例如,考虑以下预期的输入和输出:

输入:3+2/1+90

输出:3+2/1+90+2

[编辑] 我听说过 Haskell 的惰性求值,但我只是意识到这正是我想要的,只要我不调用打印,实际上解析树中不会进行任何求值。

4

1 回答 1

8

在 Haskell 中,事情总是懒惰的,所以你总是会有一个等效的计算,3+2/1+90+2但是当你要求打印版本时,你会评估它。

你可以做这样的事情

f x = x + 2

main = do
  let x = f (error "Kaboom!!")
  print 1

运行它就好了,但试图打印它会强制评估。

main = do
   let x = f (error "Kaboom!!")
   print x

哪个会出错。这个故事在评估多少/何时评估事物方面有一些微妙之处,但这就是它的要点。

在这一点上,Haskell 已经失去了“漂亮打印”计算的所有能力,所有信息都被编译成显式闭包和其他丑陋的东西。如果你想观察计算的建立,有一个有趣的技巧

newtype TraceableNum = Trace { runTrace :: String }

instance Num TraceableNum where
   (Trace a) + (Trace b) = Trace $ "(" ++ a ++ " + " ++ b ++ ")"
   (Trace a) - (Trace b) = Trace $ "(" ++ a ++ " - " ++ b ++ ")"
   (Trace a) * (Trace b) = Trace $ "(" ++ a ++ " * " ++ b ++ ")"
   abs (Trace a) = Trace $ "abs(" ++ a ++ ")"
   signum (Trace a) = Trace $ "signum(" ++ a ++ ")"
   fromInteger = Trace . show

 main = print . runTrace $ 1 + 4 * 7

Daniel Wagner 指出如果你想继续这个想法:simple-reflect

于 2013-09-17T02:52:03.727 回答