在正在运行的haskell程序中生成输出

Ihm*_*ahr 4 monads haskell on-the-fly

来自(SWI)Prolog我发现很难让Haskell动态提供输出.

最简单的例子,我希望Haskell在每次迭代时打印一些东西:

fac 0 = 1  
fac n = fac ( n-1 ) * n
Run Code Online (Sandbox Code Playgroud)

或者我想从一个永不停止的程序中获得输出...

-- A possible halt statement...  
-- find_primes l 100 = l  
find_primes l n = if ( is_prime l n ) then find_primes nn s else find_primes l s  
where   s = n + 1
nn = n:l

is_prime :: Integral a => [a] -> a -> Bool  
is_prime [] n = True  --print the prime number on the fly    
is_prime (h:t) n = if ( r /= 0 ) then is_prime t n else False  
where r =  n mod h
Run Code Online (Sandbox Code Playgroud)

前奏> find_primes [] 2

rkh*_*rov 13

你有三个选择:

第一:传播IO到处都是用Haskell写的,就像花哨的命令式语言一样.

fac 0 = putStrLn "0! = 1" >> return 1
fac n = do
    x <- fac (n - 1)
    let r = x * n
    putStrLn $ show n ++ "! = " ++ show r
    return r
Run Code Online (Sandbox Code Playgroud)

第二:使用unsafePerformIO及其衍生物(例如Debug.Trace).用于拍摄自己的脚和调试目的.

第三:代替在代码中混合I/O和计算,懒惰地生成一个[潜在无限]数据结构,其中包含纯函数中的中间结果并单独使用它.例如,无穷大的阶乘列表可以写成:

facs = scanl (*) 1 [1..]
Run Code Online (Sandbox Code Playgroud)

并按如下方式使用,以产生与fac 10上述示例中的调用相同的结果:

forM_ (take 11 $ zip [0..] facs) $ \(i, x) ->
    putStrLn $ show i ++ "! = " ++ show x
Run Code Online (Sandbox Code Playgroud)

  • 在这些选项中,第三个是最好的. (8认同)