Почему у меня вывод "()" и как это исправить? - PullRequest
0 голосов
/ 27 мая 2020

Я работаю с поворотом текста из txt файла, я застрял на самом простом - выводе обратно в тот же файл. В конце программы в тестовом файле (output.txt) появляется «()». Я знаю, что нужно как-то переписать main2, но не знаю, как именно. Думаю, есть проблема с побочными эффектами. Так что делать? Буду рад получить вашу помощь

import System.IO

getPixel :: [[Char]] -> Int -> Int -> Char
getPixel img x y
  | x >= 0 && x < width && y >= 0 && y < height = img !! y !! x
  | otherwise = ' '
  where
    height = length img
    width = length $ head img

rotate :: Double -> (Double, Double) -> (Double, Double)
rotate a (x, y) = (x * cos a + y * sin a, -x * sin a + y * cos a)

main :: IO ()
main = do
    output <- main2
    writeFile "output.txt" (show output)

main2 :: IO ()
main2 = do
    image <- lines <$> readFile "input.txt"
    mapM_ putStrLn $ do
        y <- [0 .. 30]
        return $ do
            x <- [0 .. 40]
            let (x', y') = rotate (pi/3) (x-5, y-1)
            return $ getPixel image (floor x') (floor y')

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

В конце программы () появляется в тестовом файле (output.txt)

Причина, по которой он пишет (), состоит в том, что подпись main2 это main2 :: IO (). Это означает, что output в output <- main2 будет типом модуля [wiki] , и, таким образом, show () вернет строку "()".

Но на самом деле вам не обязательно использовать здесь mapM_. Вы можете создать функцию, которая будет для данного [[Char]] генерировать список символов, например:

rotateImg :: (Int -> Int -> Char) -> [Int] -> [Int] -> <b>[[Char]]</b>
rotateImg getPix ys xs = [
    [ getPix (floor x) (floor y) | x' <- xs, let (x, y) = rotate (pi/3) (fromIntegral (x'-5), fromIntegral (y'-1)) ]
    | y' <- ys
  ]

Итак, тогда мы можем определить в main функцию, которая затем считывает информацию об изображении, поворачивает изображение и, наконец, записывает повернутое изображение в файл (или печатает его в стандартный вывод):

main :: IO ()
main = do
    image <- lines <$> readFile "input.txt"
    let image2 = <b>rotateImg (getPixel image) [0..30] [0..40]</b>
    writeFile "output.txt" (unlines output)
0 голосов
/ 27 мая 2020

Измените main2 :: IO () на main2 :: [Char]. Ну и от mapM_ до mapM.

Я больше ничего не вижу, так что это должно исправить.

...