#lang plai-typed (require [typed-in racket (substring : (string number number -> string))] [typed-in racket (string-length : (string -> number))]) ; 2012 (define-type (tv-pair 'a 'b) [tv (tag : 'a) (value : 'b)]) (define (wc-map [file : (tv-pair string string)]) : (listof (tv-pair string number)) (map (lambda ([word : string]) : (tv-pair string number) (tv word 1)) (parse-words (tv-value file)))) (define (wc-reduce [word-counts : (tv-pair string (listof number))]) : (tv-pair string number) (tv (tv-tag word-counts) (length (tv-value word-counts)))) ; words can be divided by any number of spaces (define (parse-words [text : string]) : (listof string) (cond [(string=? "" text) empty] [else (local [(define word (take-til " " text))] (cons word (parse-words (rmv-spaces (substring text (string-length word) (string-length text))))))])) ; removes spaces from front until a letter is hit (define (rmv-spaces [str : string]) : string (cond [(string=? "" str) ""] [(string=? (substring str 0 1) " ") (rmv-spaces (substring str 1 (string-length str)))] [else str])) ; takes from the front of a string until it hits c (define (take-til [c : string] [str : string]) : string (cond [(string=? "" str) ""] [(string=? c (substring str 0 1)) ""] [else (string-append (substring str 0 1) (take-til c (substring str 1 (string-length str))))]))