def SH.genInput sopts copts := if io $ isEof () then [] else let line := io $ readLine () x := TSV.parseLine sopts copts line in seq x (x :: SH.genInput sopts copts) def TSV.map fn showFn := do let eof := isEof () if eof then return () else do let line := readLine () print (showFn (fn (readTsv line))) TSV.map fn showFn def TSV.filter fn := do let eof := isEof () if eof then return () else do let line := readLine () if fn (readTsv line) then print line else return () TSV.filter fn def TSV.parseLine sopts copts line := readTsv (S.intercalate "\t" (fnC copts (fnS sopts (S.split "\t" line)))) where fnS sopts xs := match sopts as list (list integer) with | [$m] :: $opts' -> let (hs, ts) := splitAt (m - 1) xs in fnS opts' (hs ++ map (\t -> S.concat ["\"", t, "\""]) ts) | [$m, #m] :: $opts' -> let (hs, ts') := splitAt (m - 1) xs (mf, ts) := uncons ts' in fnS opts' (hs ++ S.concat ["\"", mf, "\""] :: ts) | [$m, $n] :: $opts' -> let (hs, ts') := splitAt (m - 1) xs (ms, ts) := splitAt (n - m + 1) ts' in fnS opts' (hs ++ map (\m -> S.concat ["\"", m, "\""]) ms ++ ts) | [$m, _] :: $opts' -> fnS ([m] :: opts') xs | _ -> xs fnC copts xs := match copts as list (list integer) with | [$m] :: $opts' -> let (hs, ts) := splitAt (m - 1) xs in fnC opts' (hs ++ [S.concat ["[", S.intercalate ", " ts, "]"]]) | [$m, #m] :: $opts' -> let (hs, ts') := splitAt (m - 1) xs (mf, ts) := uncons ts' in fnC opts' (hs ++ S.concat ["[", mf, "]"] :: ts) | [$m, $n] :: $opts' -> let (hs, ts') := splitAt (m - 1) xs (ms, ts) := splitAt (n - m + 1) ts' in fnC opts' (hs ++ S.concat ["[", S.intercalate ", " ms, "]"] :: ts) | [$m, _] :: $opts' -> fnC ([m] :: opts') xs | _ -> xs def TSV.show := showTsv