This module provides a large suite of utilities that resemble Unix
utilities.
Many of these commands are just existing Haskell commands renamed to
match their Unix counterparts:
>>> :set -XOverloadedStrings
>>> cd "/tmp"
>>> pwd
FilePath "/tmp"
Some commands are
Shells that emit streams of values.
view prints all values in a
Shell stream:
>>> view (ls "/usr")
FilePath "/usr/lib"
FilePath "/usr/src"
FilePath "/usr/sbin"
FilePath "/usr/include"
FilePath "/usr/share"
FilePath "/usr/games"
FilePath "/usr/local"
FilePath "/usr/bin"
>>> view (find (suffix "Browser.py") "/usr/lib")
FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py"
FilePath "/usr/lib/python3.4/idlelib/RemoteObjectBrowser.py"
FilePath "/usr/lib/python3.4/idlelib/PathBrowser.py"
FilePath "/usr/lib/python3.4/idlelib/ObjectBrowser.py"
Use
fold to reduce the output of a
Shell stream:
>>> import qualified Control.Foldl as Fold
>>> fold (ls "/usr") Fold.length
8
>>> fold (find (suffix "Browser.py") "/usr/lib") Fold.head
Just (FilePath "/usr/lib/python3.4/idlelib/ClassBrowser.py")
Create files using
output:
>>> output "foo.txt" ("123" <|> "456" <|> "ABC")
>>> realpath "foo.txt"
FilePath "/tmp/foo.txt"
Read in files using
input:
>>> stdout (input "foo.txt")
123
456
ABC
Format strings in a type safe way using
format:
>>> dir <- pwd
>>> format ("I am in the "%fp%" directory") dir
"I am in the /tmp directory"
Commands like
grep,
sed and
find accept arbitrary
Patterns
>>> stdout (grep ("123" <|> "ABC") (input "foo.txt"))
123
ABC
>>> let exclaim = fmap (<> "!") (plus digit)
>>> stdout (sed exclaim (input "foo.txt"))
123!
456!
ABC
Note that
grep and
find differ from their Unix
counterparts by requiring that the
Pattern matches the entire
line or file name by default. However, you can optionally match the
prefix, suffix, or interior of a line:
>>> stdout (grep (has "2") (input "foo.txt"))
123
>>> stdout (grep (prefix "1") (input "foo.txt"))
123
>>> stdout (grep (suffix "3") (input "foo.txt"))
123
You can also build up more sophisticated
Shell programs using
sh in conjunction with
do notation:
{-# LANGUAGE OverloadedStrings #-}
import Turtle
main = sh example
example = do
-- Read in file names from "files1.txt" and "files2.txt"
file <- fmap fromText (input "files1.txt" <|> input "files2.txt")
-- Stream each file to standard output only if the file exists
True <- liftIO (testfile file)
line <- input file
liftIO (echo line)
See
Turtle.Tutorial for an extended tutorial explaining how to
use this library in greater detail.