This is a cobbled together quick hack of Programming Praxis’ Crypt problem.

> import Data.Bits
> import Data.Char
> import Data.Function
> import System.Environment

The crypt function takes a key and a plain- or ciphered-text, then returns the toggled version.

> crypt :: String -> String -> String
> crypt k t = map chr . zipWith (xor `on` ord) t $ cycle k

The main function is a case that switches between three behaviours: no arguments prints a usage message, one argument interacts with standard input, and at least two arguments encrypts or decrypts a file to standard output.

> main = do
>     args <- getArgs
>     case length args of
>         0 -> do
>             name <- getProgName
>             putStrLn $ "Usage: " ++ name ++ " key [filename]"
>         1 -> interact . crypt $ head args
>         _ -> do
>             let (k:f:_) = args
>             contents <- readFile f
>             putStr $ crypt k contents