在Haskell中调试<< loop >>错误消息

时间:2018-12-05 08:54:21

标签: debugging haskell

您好,我在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

主要

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 :(得分:7)

TextEncode Readme实例中,lendat相互依赖:

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

答案 1 :(得分:2)

正如夏丽瑶所说,部分问题是无限递归,但是如果您尝试了以下代码,则问题仍然存在。

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)