使用`seq`并在haskell中打印 [英] Use `seq` and print in haskell

查看:166
本文介绍了使用`seq`并在haskell中打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 模块Main这里

sillyDebug :: Int - > Int - > Int
sillyDebug xy =
(print x)`seq`(x + y)

main :: IO()
main = do
print (sillyDebug 1 2)

理想情况与 $相同b $ b

  sillyDebug =(trace(show x)False)`seq`(x + y)

它与haskell中的懒惰评估或副作用有关吗?
https://hackhands.com/lazy-evaluation-works-haskell/

解决方案

仅仅评估一些 IO 什么都没有。你可以认为 IO 有点像Haskell 可以做的所有可能的副作用的一种非常大的总和类型,即使它不是'实际上就是这样实现的。像这样:

  data IO a where 
PutStrLn :: String - > IO()
ReadFile :: FilePath - > IO字符串
ExitWith :: ExitCode - > IO a
...

其中一个 IO <这个理论可视化中的code>构造函数是一个 Sequence 构造函数,类型签名是这样的:

  Sequence:IO a  - > (a→IO b)→> IO b 

这个构造函数用于实现>> = > 类型。

GHC内部是一个神奇的函数,名为 magicallyExecuteIO 键入 IO a - >>一个,它为每个动作协调实际执行其相应的副作用。 (顺便说一句,这个函数有时也被读作 unsafePerformIO 。)GHC隐式地调用 magicallyExecuteIO 来获取程序结果 main 函数以及用GHCi编写的表达式。

然而,如果不使用 magicallyExecuteIO ,评估其中一个 IO 构造函数,如 PutStrLn 不会执行任何操作。在这个实现中,它可以像任何其他数据构造函数一样工作:

  ghci> Just(PutStrLnhello!)
Just(PutStrLnhello!):: Maybe(IO())

(我使用 Just 来包装它,以防止GHCi运行 IO 操作。 )

当然,GHC的实际 IO 类型不是这样实现的,但这实际上只是一个实现细节。评估一个 IO a 值不会导致副作用的发生,而不是评估一个也许一个值会。只有 magicallyExecuteIO 可以做到这一点。


I know that this is a little bit tricky but i wonder why it doesn't work!

module Main where

sillyDebug :: Int -> Int -> Int
sillyDebug x y =
    (print x) `seq` (x + y)

main :: IO ()
main = do
    print (sillyDebug 1 2)

while its ideal is the same as

sillyDebug = (trace (show x) False) `seq` (x + y)

Is it related to lazy evaluation or side effect in haskell? https://hackhands.com/lazy-evaluation-works-haskell/

解决方案

Merely evaluating some IO action doesn’t do anything at all. You can think of IO sort of like a really big sum type of all the possible side-effectful things Haskell can do, even if it isn’t actually implemented like that at all. Something like this:

data IO a where
  PutStrLn :: String -> IO ()
  ReadFile :: FilePath -> IO String
  ExitWith :: ExitCode -> IO a
  ...

One of the IO constructors in this theoretical visualization would be a Sequence constructor, with a type signature like this:

  Sequence :: IO a -> (a -> IO b) -> IO b

This constructor is used to implement >>= for the IO type.

Inside of GHC is a magical function called magicallyExecuteIO with type IO a -> a, which coordinates for each action to actually perform its corresponding side-effect. (Incidentally, this function is also sometimes pronounced unsafePerformIO.) GHC implicitly calls magicallyExecuteIO on the result of your program’s main function, as well as on expressions written in GHCi.

However, without using magicallyExecuteIO, evaluating one of the IO constructors like PutStrLn doesn’t do anything. In this implementation, it would just work like any other data constructor:

ghci> Just (PutStrLn "hello!")
Just (PutStrLn "hello!") :: Maybe (IO ())

(I’ve wrapped it with Just to prevent GHCi from running the IO action.)

Of course, GHC’s actual IO type isn’t implemented this way, but that’s really just an implementation detail. Evaluating an IO a value doesn’t cause a side-effect to happen any more than evaluating a Maybe a value does. Only magicallyExecuteIO can do that.

这篇关于使用`seq`并在haskell中打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆