loadMtx :: String -> IO [[Double]] -- парсер loadMtx text = do delete [] (map (map(read)) ((map (delete "") (map (map (strip)) (map (Data.List.Split.splitOn " ") (splitOn ";" text)))))) main = do text <- readFile "matrix.txt" mtx <- loadMtx text putStrLn $ show $ mtx 

Issues:

 Couldn't match expected type `IO [Double]' with actual type `[[a0]]' In the return type of a call of `delete' 

In general, I did not fully understand IO (), but there is a need to save the finished matrix, because I do not want to reread the file every time. How to do it?

  • one
    What prevents to do: loadMtx :: String -> [[Double]] loadMtx text = delete ... .... main = do ... putStrLn $ show $ mtx where mtx = loadMtx text - andrybak
  • main.hs: 20: 31: Not in scope: `text ' - the name is too short
  • As wrote @ Andrew, what for loadMtx type IO [[Double]]? (By the way, in the error message, the type is generally IO [Double]. But if you need a monad, then there is a function return :: Monad m => a -> ma ie return $ delete [] (map ... - alexlz
  • I don’t have to use IO, otherwise I don’t understand how to assign a value inside main (how to organize the code, for example?), So that I don’t reread the file each time to generate the matrix. - the name is too short
  • 2
    @ The name is too short to not reread the file each time to generate the matrix. What are you talking about? Haskell is not Ce and not Java. And not even php. He is lazy @ Andrew, well, the file is not a file. With the outside world - alexlz

1 answer 1

Assuming that matrix.txt looks like

 1.0 2.0 3.0; 4.0 5.0 6.0 ; 7.0 8.0 9.0 

You can use the following code:

 import Data.List import Data.List.Split parseMtx :: String -> [[Double]] parseMtx text = map (map read) $ delete [] $ map words $ splitOn ";" text main :: IO () main = do text <- readFile "matrix.txt" let mtx = parseMtx text print mtx 

The words function splits the string into "words", eating all the spaces between them.

If mtx used further in the code, the file will not be reread and the matrix will be built only once.

As an exercise, you can rewrite parseMtx in the parseMtx notation:

 parseMtx :: String -> [[Double]] parseMtx = map (map read) . delete[] . map words . splitOn ";"