X-Git-Url: https://mattmccutchen.net/match/match.git/blobdiff_plain/e95df3f5aa9099829c63bab4a5c5ea96808edeb0..bbabbd0161ab6e633f7d7027e0167892633519f7:/program/Main.hs diff --git a/program/Main.hs b/program/Main.hs new file mode 100644 index 0000000..4487508 --- /dev/null +++ b/program/Main.hs @@ -0,0 +1,40 @@ +import PMInstance +import PMDefaults +import ProposalMatcher +import System.IO +import Data.Array.IArray +import Data.Array.Unboxed +import ArrayStuff +import Text.CSV + +-- Command-line interface with simple tab-separated input/output formats. +-- ./match if c == '\t' then ',' else if c == ',' then '\t' else c) s +removeQuotes s = filter (\c -> not (c == '"')) s + +-- Some versions of Text.CSV do not use or accept a trailing newline; compensate for that. +removeTrailingNewline s = if not (null s) && last s == '\n' then init s else s +addTrailingNewline s = if not (null s) && last s /= '\n' then s ++ ['\n'] else s + +parseTSV fname str = case parseCSV fname (swapTabCommaIn $ removeTrailingNewline str) of + Left pe -> Left pe + Right ll -> Right $ map (map swapTabCommaIn) ll +printTSV ll = addTrailingNewline $ removeQuotes $ swapTabCommaIn $ printCSV $ map (map swapTabCommaIn) ll + +main = do + incsv <- hGetContents stdin + -- handle errors another day, or let the platform do it + let Right inll = parseTSV "standard input" incsv + let loadList = head inll + let numRvrs = length loadList + let loadA = listArray (0, numRvrs-1) (map read loadList) + let numProps = length (tail inll) + -- explicit type on the next line appears to be necessary + let pxarr = listOfListsToArray2D (tail inll) :: Array (Int,Int) String + -- careful, we end up transposing the array in here + let prefA = funcArray ((0,0), (numRvrs-1,numProps-1)) (\(i,j) -> read (pxarr ! (j, i))) + let theInst = PMInstance numRvrs numProps loadA prefA + let PMatching theMatching = doMatching pmDefaults theInst + hPutStr stdout $ printTSV $ map (\(i, j) -> map show [i, j]) theMatching