Last active
February 17, 2021 14:40
-
-
Save fkurz/cf00cf22acb6f40879c47e34074f991a to your computer and use it in GitHub Desktop.
Revisions
-
fkurz revised this gist
Feb 17, 2021 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -149,4 +149,5 @@ In a terminal emulator like [iTerm](https://iterm2.com/), we can start _hsh_ in ## SOURCES * https://downloads.haskell.org/~ghc/7.6.3/docs/html/users_guide/ghci-dot-files.html * https://bobkonf.de/2017/slides/thoma.pdf -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -138,7 +138,7 @@ The [Turtle tutorial on Hackage](https://hackage.haskell.org/package/turtle-1.5. ### Launching GHCI Directly in Your Terminal Emulator In a terminal emulator like [iTerm](https://iterm2.com/), we can start _hsh_ in every new window/tab in order to get a complete Haskell based Terminal feeling. ## Future Work -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -113,7 +113,7 @@ There are a couple cool aspects of Haskell/GHCI that are being used to provide a 2. overloaded strings: E.g. `echo` has type `echo :: MonadIO io => Line -> io ()` (i.e. expects `Line` not `String`) which can however use the overloaded string literal syntax ```haskell λ> echo "Hi!" -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -96,7 +96,7 @@ In the ghci REPL we can now use the Turtle library to do system programming simi ### The Good There are a couple cool aspects of Haskell/GHCI that are being used to provide a proper shell feeling: 1. monads: most Turtle functions like `dir` and `echo` are monadic -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 5 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -67,7 +67,7 @@ Can Haskell be a good replacement for Bash—or similar languages—as a shell s 4. Run Haskell Shell and have fun :raised_hands: ```bash $ hsh -e git -e latexmk -e typora [INFO] Creating hsh config [INFO] hsh setup done [INFO] Creating function for command git @@ -109,8 +109,6 @@ There are two very cool aspects of Haskell/GHCI that are being used here: ```haskell λ> dir <- pwd ``` 2. overloaded strings: @@ -121,11 +119,12 @@ There are two very cool aspects of Haskell/GHCI that are being used here: λ> echo "Hi!" ``` 3. printing of return values: types like `FilePath` are printable and GHCI prints every value that is entered so we can immediately see results of commands ```haskell λ> dir <- pwd λ> dir FilePath "/Users/friedrichk/.hsh" ``` The [Turtle tutorial on Hackage](https://hackage.haskell.org/package/turtle-1.5.21/docs/Turtle-Tutorial.html) has more examples. Be sure to check it out. -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -110,7 +110,7 @@ There are two very cool aspects of Haskell/GHCI that are being used here: ```haskell λ> dir <- pwd λ> dir FilePath "/Users/main/.hsh" ``` 2. overloaded strings: -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -67,7 +67,7 @@ Can Haskell be a good replacement for Bash—or similar languages—as a shell s 4. Run Haskell Shell and have fun :raised_hands: ```bash $ hsh -e git [INFO] Creating hsh config [INFO] hsh setup done [INFO] Creating function for command git -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 43 additions and 42 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -29,66 +29,67 @@ Can Haskell be a good replacement for Bash—or similar languages—as a shell s ```bash hsh_setup() { local hsh_home="${HOME}/.hsh" mkdir -p ${hsh_home} printf "[INFO] Creating hsh config" printf ':set -XOverloadedStrings\n:set prompt "λ> "\n:set +m\nimport Turtle\nimport Prelude hiding (FilePath)' > ${hsh_home}/.ghci printf "\n[INFO] hsh setup done" } hsh_extend() { local hsh_home="${HOME}/.hsh" \ command=${1} printf "\n[INFO] Creating function for command %-25s" "${command}" printf "\n%1\$s = \\\cl -> shell (\"%1\$s \" <> cl) empty\n%1\$s' = \\\cl -> shell (\"%1\$s \" <> cl)" ${command} >> ${hsh_home}/.ghci } hsh_init() ( local hsh_home="${HOME}/.hsh" hsh_setup while getopts "e:" option; do case ${option} in e) hsh_extend ${OPTARG} esac done cd ${hsh_home} stack ghci ) alias hsh=hsh_init ``` 4. Run Haskell Shell and have fun :raised_hands: ```bash $ hsh -e git -e latexmk -e typora [INFO] Creating hsh config [INFO] hsh setup done [INFO] Creating function for command git [INFO] Creating function for command latexmk [INFO] Creating function for command typora Note: No local targets specified, so a plain ghci will be started with no package hiding or package options. You are using snapshot: lts-17.2 If you want to use package hiding and options, then you can try one of the following: * If you want to start a different project configuration than /Users/main/.stack/global-project/stack.yaml, then you can use stack init to create a new stack.yaml for the packages in the current directory. * If you want to use the project configuration at /Users/main/.stack/global-project/stack.yaml, then you can add to its 'packages' field. Configuring GHCi with the following packages: GHCi, version 8.10.3: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /Users/main/.hsh/.ghci Loaded GHCi configuration from /private/var/folders/yz/b655kl71057db1lhwxhc0rt00000gs/T/haskell-stack-ghci/2a3bbd58/ghci-script ``` In the ghci REPL we can now use the Turtle library to do system programming similar to what we awould do in Bash. :rocket: -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 57 additions and 70 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,83 +25,70 @@ Can Haskell be a good replacement for Bash—or similar languages—as a shell s stack install turtle ``` 3. Define functions to setup/init/extend Haskell shell and create an alias _hsh_ ```bash hsh_setup() { local hsh_home="${HOME}/.hsh" mkdir -p ${hsh_home} printf "[INFO] Creating hsh config" printf ':set -XOverloadedStrings\n:set prompt "λ> "\n:set +m\nimport Turtle\nimport Prelude hiding (FilePath)' > ${hsh_home}/.ghci printf "\n[INFO] hsh setup done" } hsh_extend() { local hsh_home="${HOME}/.hsh" \ command=${1} printf "\n[INFO] Creating function for command %-25s" "${command}" printf "\n%1\$s = \\\cl -> shell (\"%1\$s \" <> cl) empty\n%1\$s' = \\\cl -> shell (\"%1\$s \" <> cl)" ${command} >> ${hsh_home}/.ghci } hsh_init() ( local hsh_home="${HOME}/.hsh" hsh_setup while getopts "e:" option; do case ${option} in e) hsh_extend ${OPTARG} esac done cd ${hsh_home} stack ghci ) alias hsh=hsh_init ``` 4. Run Haskell Shell and have fun :raised_hands: ```bash $ hsh -e git -e latexmk [INFO] Creating hsh config [INFO] hsh setup done [INFO] Creating function for command git [INFO] Creating function for command latexmk Note: No local targets specified, so a plain ghci will be started with no package hiding or package options. You are using snapshot: lts-17.2 If you want to use package hiding and options, then you can try one of the following: * If you want to start a different project configuration than /Users/main/.stack/global-project/stack.yaml, then you can use stack init to create a new stack.yaml for the packages in the current directory. * If you want to use the project configuration at /Users/main/.stack/global-project/stack.yaml, then you can add to its 'packages' field. Configuring GHCi with the following packages: GHCi, version 8.10.3: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /Users/main/.hsh/.ghci Loaded GHCi configuration from /private/var/folders/yz/b655kl71057db1lhwxhc0rt00000gs/T/haskell-stack-ghci/2a3bbd58/ghci-script ``` In the ghci REPL we can now use the Turtle library to do system programming similar to what we awould do in Bash. :rocket: -
fkurz revised this gist
Feb 13, 2021 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -127,7 +127,7 @@ There are two very cool aspects of Haskell/GHCI that are being used here: 2. overloaded strings: * E.g. `echo` has type `echo :: MonadIO io => Line -> io ()` (i.e. expects `Line` not `String`) which can however use the overloaded string literal syntax ```haskell λ> echo "Hi!" -
fkurz created this gist
Feb 13, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,165 @@ # Shell scripting with Haskell ## Problem Shell scripting is kinda broken: * Shell scripting languages differ or are interpreted with subtle differences * Higher level language concepts are typically missing Can Haskell be a good replacement for Bash—or similar languages—as a shell scripting language? ## Using GHCI for System Programing ### Setup 1. Install Haskell Stack ```bash brew install haskell-stack ``` 2. Install [turtle](http://hackage.haskell.org/package/turtle) using Stack ```bash stack install turtle ``` 3. Define functions to setup/init hash and create an alias _hsh_ ```bash # Haskell shell (hsh) setup_hsh() { set -f local binary_name \ sanitized_binary_name \ hsh_config="${HOME}/.hsh/.ghci" \ reserved_keywords=("case" "class" "data" "default" "deriving" "do" "else" "forall" "if" "import" "in" "infix" "infixl" "infixr" "instance" "let" "module" "newtype" "of" "qualified" "then" "type" "where" "_" "foreign" "ccall" "as" "safe" "unsafe") # TODO incomplete turtle_functions=("cd" "pwd" "ls") mkdir -p ~/.hsh printf "[INFO] Creating hsh config\n" printf ':set -XOverloadedStrings\n:set prompt "λ> "\n:set +m\nimport Turtle\nimport Prelude hiding (FilePath)' > "${hsh_config}" for p in $(print -rC1 -- $commands); do binary_name=${p##*/}; sanitized_binary_name=$(echo "${binary_name//[^[:alnum:]]/_}" | tr '[:upper:]' '[:lower:]') if [[ "${sanitized_binary_name}" =~ ^[a-z_][a-zA-Z_]*$^ ]] \ && ! [[ ${reserved_keywords[*]} =~ "${sanitized_binary_name}" ]] \ && ! [[ ${turtle_functions[*]} =~ "${sanitized_binary_name}" ]]; then printf "\r[INFO] Creating function for command %-25s" "${binary_name}" printf "\n%2\$s = \\\cl -> shell (\"%1\$s \" <> cl) empty\n%2\$s' = \\\cl -> shell (\"%1\$s \" <> cl)" "${binary_name}" "${sanitized_binary_name}" >> "${hsh_config}" fi done printf "\n[INFO] hsh setup done" } hsh_init() { set -f local hsh_config="${HOME}/.hsh/.ghci" \ run_setup="false" while getopts "s" option; do case "${option}" in s) run_setup="true";; esac done { [[ ! -f ${hsh_config} ]] || [[ ${run_setup} == "true" ]] } && setup_hsh (cd "${HOME}/.hsh" && stack ghci) } alias hsh=hsh_init ``` 4. Run Haskell Shell and have fun :raised_hands: ```bash $ hsh Note: No local targets specified, so a plain ghci will be started with no package hiding or package options. You are using snapshot: lts-17.0 If you want to use package hiding and options, then you can try one of the following: * If you want to start a different project configuration than /Users/friedrichk/.stack/global-project/stack.yaml, then you can use stack init to create a new stack.yaml for the packages in the current directory. * If you want to use the project configuration at /Users/friedrichk/.stack/global-project/stack.yaml, then you can add to its 'packages' field. Configuring GHCi with the following packages: GHCi, version 8.10.3: https://www.haskell.org/ghc/ :? for help Loaded GHCi configuration from /Users/friedrichk/.ghc/ghci.conf Loaded GHCi configuration from /Users/friedrichk/.hsh/.ghci Loaded GHCi configuration from /private/var/folders/fc/p5cjtnhd6sdfsbp9tfbtlmqnskrnk7/T/haskell-stack-ghci/2a3bbd58/ghci-script ``` In the ghci REPL we can now use the Turtle library to do system programming similar to what we awould do in Bash. :rocket: ### The Good There are two very cool aspects of Haskell/GHCI that are being used here: 1. monads: most Turtle functions like `dir` and `echo` are monadic ```haskell λ> :t pwd pwd :: MonadIO io => io FilePath ``` and GHCI executes code within an IO monad; that means we can write in do-notation style and read/write from/to input/output ```haskell λ> dir <- pwd λ> dir FilePath "/Users/friedrichk/.hsh" ``` 2. overloaded strings: * E.g. `echo` has type ``echo :: MonadIO io => Line -> io ()` (i.e. expects `Line` not `String`) which can however use the overloaded string literal syntax ```haskell λ> echo "Hi!" ``` 3. printing of return values: return of echo is something that is printable and GHCI therefore prints it nicely ```haskell λ> echo "Hi!" Hi! ``` The [Turtle tutorial on Hackage](https://hackage.haskell.org/package/turtle-1.5.21/docs/Turtle-Tutorial.html) has more examples. Be sure to check it out. ### The Bad * No Tab-Completion for commands/paths * No Syntax-Highlighting ## Bonus Round ### Launching GHCI Directly in Your Terminal Emulator In a terminal emulator like [iTerm](https://iterm2.com/), we can start _hsh_ in every new window/tab in order to get a complete Haskell based Shell feeling. ## Future Work [*ptghci*](https://github.com/litxio/ptghci) adds useful features like syntax highlighting and tab completion and might be a good extension. --- ## SOURCES * https://downloads.haskell.org/~ghc/7.6.3/docs/html/users_guide/ghci-dot-files.html