Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Couldn't match type `[]' with `IO' -- Haskell

I'm beginner in Haskell. In this task i'm performing the split operation but i'm facing problem because of type mis match. I'm reading data from text file and the data is in table format. Ex. 1|2|Rahul|13.25. In this format. Here | is delimiter so i want to split the data from the delimiter | and want to print 2nd column and 4th column data but i'm getting the error like this

  "Couldn't match type `[]' with `IO'
    Expected type: IO [Char]
      Actual type: [[Char]]
    In the return type of a call of `splitOn'"

Here is my code..

module Main where

import Data.List.Split

main = do
    list <- readFile("src/table.txt")
    putStrLn list
    splitOn "|" list

Any help regarding this will appreciate.. Thanks

like image 839
Rahul Avatar asked Aug 23 '14 22:08

Rahul


2 Answers

The problem is that you're trying to return a list from the main function, which has a type of IO ().

What you probably want to do is print the result.

main = do
    list <- readFile("src/table.txt")
    putStrLn list
    print $ splitOn "|" list
like image 172
Jakub Arnold Avatar answered Sep 21 '22 22:09

Jakub Arnold


Not Haskell, but it looks like a typical awk task.

cat src/table.txt | awk -F'|' '{print $2, $4}'

Back to Haskell the best I could find is :

module Main where

import Data.List.Split(splitOn)
import Data.List (intercalate)

project :: [Int] -> [String] -> [String]
project indices l = foldl (\acc i -> acc ++ [l !! i]) [] indices

fromString :: String -> [[String]]
fromString = map (splitOn "|") . lines

toString :: [[String]] -> String
toString = unlines . map (intercalate "|")

main :: IO ()
main = do
  putStrLn =<<
    return . toString . map (project [1, 3]) . fromString =<<
    readFile("table.txt")

If not reading from a file, but from stdin, the interact function could be useful.

like image 30
Jean-Baptiste Potonnier Avatar answered Sep 18 '22 22:09

Jean-Baptiste Potonnier