假设我们有这样的函数:
f:Int->Int
Run Code Online (Sandbox Code Playgroud)
它为我们提供了基于输入的修改输出.
我的问题是,无论如何我可以编写这个函数,所以没有对输入进行评估吗?例如,考虑以下预期的输入和输出:
输入:3 + 2/1 + 90
输出:3 + 2/1 + 90 + 2
[编辑] 我听说过Haskell的懒惰评估,但我刚才意识到这正是我想要的,只要我不调用print,实际上在解析树中没有进行评估.
在Haskell中,事情总是很懒惰,所以你总是会有一个相当的计算,3+2/1+90+2但是当你要求印刷版本时,你会对它进行评估.
你可以做这样的事情
f x = x + 2
main = do
let x = f (error "Kaboom!!")
print 1
Run Code Online (Sandbox Code Playgroud)
并运行它很好,但试图打印它将迫使评估.
main = do
let x = f (error "Kaboom!!")
print x
Run Code Online (Sandbox Code Playgroud)
哪个会出错.这个故事有一些细微之处在于评估事物的时间/时间,但这是它的要点.
在这一点上,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
Run Code Online (Sandbox Code Playgroud)
Daniel Wagner指出,如果你想继续这个想法:简单反思