Отладка <<loop>> сообщения об ошибке в haskell - PullRequest
0 голосов
/ 05 декабря 2018

Здравствуйте, я сталкиваюсь с этим сообщением об ошибке в программе на Haskell, и я не знаю, откуда происходит цикл. Методы IO почти отсутствуют, так что я могу подключиться к ним и распечатать частичный результат в терминале..

Я начинаю с файла, я читаю его, а затем есть только чистые методы. Как я могу отладить это?

Есть ли способ присоединиться к методам или создать помощника, который можетвыполните следующие действия:

Имея метод method::a->b как я могу каким-то образом обернуть его в iomethod::(a->b)->IO (a->b), чтобы иметь возможность проверить в GHCI (я хочу вставить некоторые putStrLn -s и т. д.?

PS Мои данные претерпевают преобразования IO a(->b->c->d->......)->IO x, и я не знаю, как отладить часть, которая находится в паратезе (то есть код, который содержит чистые методы)

Типы и определения и реализации классов типов

data TCPFile=Rfile (Maybe Readme) | Dfile  Samples | Empty
data Header=Header { ftype::Char}

newtype Samples=Samples{values::[Maybe Double]}deriving(Show)

data Readme=Readme{ maxClients::Int, minClients::Int,stepClients::Int,maxDelay::Int,minDelay::Int,stepDelay::Int}deriving(Show)

data FileData=FileData{ header::Header,rawContent::Text}

(>>?)::Maybe a->(a->Maybe b)->Maybe b
(Just t) >>? f=f t
Nothing >>? _=Nothing

class TextEncode a where
fromText::Text-> a


getHeader::TCPFile->Header
getHeader (Rfile _ ) = Header { ftype='r'}
getHeader (Dfile _ )= Header{ftype='d'}
getHeader _ = Header {ftype='e'}


instance Show TCPFile where
show (Rfile t)="Rfile " ++"{"++content++"}" where
    content=case t of
        Nothing->""
        Just c -> show c
show (Dfile c)="Dfile " ++"{"++show c ++ "}"

instance TextEncode Samples where
    fromText text=Samples  (map (readMaybe.unpack) cols) where
             cols=splitOn (pack ",") text



instance TextEncode Readme where
    fromText txt =let len= length dat
                      dat= case len of 
                            6 ->Prelude.take 6 .readData $ txt
                            _ ->[0,0,0,0,0,0] in 
            Readme{maxClients=Prelude.head dat,minClients=dat!!1,stepClients=dat!!2,maxDelay=dat!!3,minDelay=dat!!4,stepDelay=dat!!5} where




instance TextEncode TCPFile where
    fromText  = textToFile

Main

module Main where 
import Data.Text(Text,pack,unpack)
import Data.Text.IO(readFile,writeFile)
import TCPFile(TCPFile)

main::IO()
main=do
    dat<-readTcpFile "test.txt"
    print dat

readTcpFile::FilePath->IO TCPFile
readTcpFile path =fromText <$> Data.Text.IO.readFile path  

textToFile::Text->TCPFile
textToFile input=case readHeader input >>? (\h -> Just (FileData h input)) >>?  makeFile of
    Just r -> r
    Nothing ->Empty



readHeader::Text->Maybe Header
readHeader txt=case Data.Text.head txt of 
    'r' ->Just (Header{ ftype='r'})
    'd' ->Just (Header {ftype ='d'})
    _  -> Nothing

makeFile::FileData->Maybe TCPFile
makeFile fd= case ftype.header $ fd of
        'r'->Just (Rfile (Just (fromText . rawContent $ fd)))
        'd'->Just (Dfile (fromText . rawContent $ fd))
        _  ->Nothing 


readData::Text->[Int]
readData =catMaybes . maybeValues where
    maybeValues=mvalues.split.filterText "{}"

#all the methods under this line  are used in the above method

mvalues::[Text]->[Maybe Int]
mvalues arr=map (\x->(readMaybe::String->Maybe Int).unpack $ x) arr

split::Text->[Text]
split =splitOn (pack ",")

filterText::[Char]->Text->Text
filterText chars tx=Data.Text.filter (\x -> not (x `elem` chars)) tx

Я хочу сначала очистить Text от заданногосимволов, в нашем случае }{, затем разделите его на ,. После текстаразделяется запятыми, я хочу их проанализировать и создать либо Rfile, который содержит 6 целых чисел, либо Dfile (файл данных), который содержит любое заданное число целых чисел.

Ввод У меня есть файл со следующим содержимым: r,1.22,3.45,6.66,5.55,6.33,2.32}, и я работаю runghc main 2>err.hs

Ожидаемый вывод : Rfile (Just (Readme 1.22 3.45 6.66 5.55 6.33 2.32))

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

Как сказал Ли-Яо Ся, частью проблемы является бесконечная рекурсия, но если вы попробовали следующий код, проблема все равно останется.

instance TextEncode Readme where
    fromText txt =let len= length [1,2,3,4,5,6] --dat
                      dat= case len of 

Вторая проблема заключается в том, что файл содержит десятичнуючисла, но все функции преобразования ожидают Maybe Int, изменение определений следующих функций должно дать ожидаемые результаты, с другой стороны, вероятно, правильным решением будет то, что файл должен иметь целые, а не десятичные числа.

readData::Text->[Double]
--readData xs = [1,2,3,4,5,6,6]
readData =catMaybes . maybeValues where
    maybeValues = mvalues . split . filterText "{}"

--all the methods under this line  are used in the above method

mvalues::[Text]->[Maybe Double]
mvalues arr=map (\x->(readMaybe::String->Maybe Double).unpack $ x) arr

data Readme=Readme{ maxClients::Double, minClients::Double,stepClients::Double,maxDelay::Double,minDelay::Double,stepDelay::Double}deriving(Show)
0 голосов
/ 05 декабря 2018

В экземпляре TextEncode Readme len и dat зависят друг от друга:

instance TextEncode Readme where
    fromText txt =let len= length dat
                      dat= case len of 

Для отладки такого рода вещей, кроме как смотреть на код, одна вещьвы можете сделать это с помощью -prof -fprof-auto -rtsopts и запустить вашу программу с параметрами строки cmd +RTS -xc.Это должно напечатать трассировку, когда возникает исключение <<loop>> (или если программа зацикливается, когда вы ее убиваете (Ctrl + C)).См. Руководство GHC https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/runtime_control.html#rts-flag--xc

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...