您好,我在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))
答案 0 :(得分:7)
在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
答案 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)