4

(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

プレリュード> find_primes [ ] 2

4

2 に答える 2

13

You have three options:

First: spread IO everywhere and write in Haskell as in fancy imperative language.

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

Second: use unsafePerformIO and its derivatives (e.g. Debug.Trace). Useful for shooting yourself in the foot and debugging purposes.

Third: instead of mixing I/O and computation in the code, lazily generate a [potentially infinite] data structure containing intermediate results in a pure function and consume it separately. For example, the infinite list of factorials can be written as:

facs = scanl (*) 1 [1..]

And consumed as follows to yield the same result as in calling fac 10 in the example above:

forM_ (take 11 $ zip [0..] facs) $ \(i, x) ->
    putStrLn $ show i ++ "! = " ++ show x
于 2011-08-27T11:12:52.787 に答える
2

ルハイロフが回答でカバーしなかったオプションがさらにいくつかあります

デバッグ情報だけが必要な場合は、Debug.Tracetrace関数の使用を検討してください。

import Debug.Trace

fact :: (Ord a, Num a) => a -> a
fact n | n > 1 = traceShow n $ n * fact (n-1)
       | otherwise = traceShow n $ 1

ただし、バグハンティング以外に使用することはお勧めできません。それは絶対に製品コードに入るべきではありません。

作業中に情報をログに記録したい場合は、Writer Monadの使用を検討してください。

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

より一般化して型クラスを使用することもできますMonadWriter

于 2011-08-27T16:56:33.660 に答える