Ваша первая попытка не работает, так как приложение функции имеет приоритет над операторами. Таким образом, он анализируется как:
(tell "gcd ") ++ (show a) ++ " " ++ (show b) ++ "\n "
Во второй попытке вы каждый раз переносите строки в одноэлементный список, поэтому вы пишете список String
s (ну, все эти списки содержат одну строку, но это все равно не делает эти String
с).
Вы можете решить проблему, добавив скобки здесь:
gcd' :: Int -> Int -> Writer String Int
gcd' a b = do
tell <b>(</b>"gcd " ++ show a ++ " " ++ show b ++ " \n"<b>)</b>
if b == 0 then
return a
else
gcd' b (a `mod` b)
Например:
Prelude Control.Monad.Trans.Writer.CPS> runWriter (gcd' 15 5)
(5,"gcd 15 5 \ngcd 5 0 \n")
Обратите внимание, что для целей отладки вам удобнее использовать trace :: String -> a -> a
вместо Writer
, так как он будет лучше выполнять то, что вы хотите.