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

在正在运行的haskell程序中生成输出,haskell,monads,on-the-fly,Haskell,Monads,On The Fly,来自(SWI)Prolog,我发现让Haskell动态地给出输出非常困难 最简单的例子是,我希望Haskell在每次迭代中打印一些内容: fac 0 = 1 fac n = fac ( n-1 ) * n 或者我想从一个永不停止的程序中获得输出 -- A possible halt statement... -- find_primes l 100 = l find_primes l n = if ( is_prime l n ) then find_primes nn s els

来自(SWI)Prolog,我发现让Haskell动态地给出输出非常困难

最简单的例子是,我希望Haskell在每次迭代中打印一些内容:

fac 0 = 1  
fac n = fac ( n-1 ) * n
或者我想从一个永不停止的程序中获得输出

-- 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

序曲>查找素数[]2

您有三个选项:

第一:把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
并按如下方式使用,以产生与上述示例中调用
fac 10
相同的结果:

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

还有两个选择是rkhayrov没有的

如果您只需要调试信息,请考虑使用.< /P> 不过,我不推荐将其用于虫子搜索之外的其他用途。它绝对不应该进入生产代码

如果您想在工作时记录信息,请考虑使用.< /P>

import Control.Monad.Writer.Lazy
导入控件。应用程序(())
事实::(Ord a,Num a)=>a->Writer[String]a
事实
告诉$[show n]
如果n>1
然后
(n*)事实(n-1)
其他的
返回1

您还可以更一般地使用MonadWritertypeclass。

在这些选项中,第三个是最好的。
forM_ (take 11 $ zip [0..] facs) $ \(i, x) ->
    putStrLn $ show i ++ "! = " ++ show x
import Debug.Trace

fact :: (Ord a, Num a) => a -> a
fact n | n > 1 = traceShow n $ n * fact (n-1)
       | otherwise = traceShow n $ 1
import Control.Monad.Writer.Lazy
import Control.Applicative ((<$>))

fact :: (Ord a, Num a) => a -> Writer [String] a
fact n = do
  tell $ [show n]
  if n > 1
    then
      (n*) <$> fact (n-1)
    else
      return 1