Turtle と stack script で Turtle と stack script 用のテンプレを生成してみる



# 経緯

[Stackを使って楽しくHaskellスクリプティング](https://qiita.com/tanakh/items/1ca4ba9e1f5006a30106)と[HaskellでShellみたいなことをやるのに便利なライブラリの紹介](https://qiita.com/t10471/items/70af33487ece780b6c10)を読み実用的に感じたので，この先いくつかの script を書いて行きたい．
手始めに，"練習を兼ねて" template の generator を書いてみる．（使ったことないけどstackにはtemplate機能があったと思う．） 

# ひたすら書いていく

```haskell:tempGen.hs
#!/usr/bin/env stack
-- stack script --resolver lts-15.3
-- --package=turtle

-- |
-- This is generated by https://github.com/sgsh-gh/snippet/blob/master/tempGen.hs
-- 

{-# OPTIONS_GHC -fno-defer-type-errors #-}
{-# LANGUAGE OverloadedStrings #-}
import Turtle

main :: IO ()
main = do  
  name:_ <- arguments :: IO [Text]
  let file = fromText $ name <> ".hs"
  touch  file
  output file temp
  where
   temp = "#!/usr/bin/env stack"
     <|>  "-- stack script --resolver lts-15.3"
     <|>  "-- --package=turtle"
     <|>  "-- --package=text"
     <|>  ""
     <|>  "-- |"
     <|>  "-- This is generated by https://github.com/sgsh-gh/snippet/blob/master/template.hs"
     <|>  "-- "
     <|>  ""
     <|>  "{-# OPTIONS_GHC -fno-defer-type-errors #-}"
     <|>  "{-# LANGUAGE OverloadedStrings #-}"
     <|>  "import System.Environment (getArgs)"
     <|>  "import Turtle"
     <|>  "import qualified Data.Text as T"
     <|>  ""
```

* read :: String -> Turtle.FilePath が無く(私が見つけられてないだけ？)変換が必要だった．
  *追記（20.04.04）igrepさんよりコメントにて`decodeString`があると教えていただきました．また，このversionではargumentsを使うように変更していたためそもそも`read`のような関数は不要でした．
* gap記法を使うと `tempGen.hs: NewlineForbidden` となってしまった．
* output は権限さえあれば上書きしてしまう．

# ここまで書いて自分自身を read すれば良いことに気づく...

```Haskell:tempGen.hs
#!/usr/bin/env stack
-- stack script --resolver lts-15.3
-- --package=turtle

-- |
-- This is generated by https://github.com/sgsh-gh/snippet/blob/master/tempGen.hs
-- 

{-# OPTIONS_GHC -fno-defer-type-errors #-}
{-# LANGUAGE OverloadedStrings #-}
import Turtle

main :: IO ()
main = do
  echo "tempGen"
  
  name:_ <- arguments :: IO [Text]
  let file = fromText $ name <> ".hs"
  False <- testfile file -- とりあえず上書きしないように
  sh $ incompleteDup file

incompleteDup :: Turtle.FilePath -> Shell ()
incompleteDup file = do
  liftIO  $ touch file --  fileを作成
  let temp = limit 16 $  input "tempGen.hs" :: Shell Line -- 16行目までをtempに束縛
  liftIO $ output file $ temp -- fileにtempを書き込み
  chmod executable file -- 実行権限を付与
  echo "created"                       
```
* Text，Line，FilePathといった型の扱いに慣れが必要．
* output の第2引数の型が Line では無く Shell Line な理由がよくわからなかった．（一行ずつ書き込んでる？）

# 実行してみる

```
>> chmod u+x tempGen.hs
>> ./tempGen.hs test
>> ls
nthPrime.hs* tempGen.hs*  test.hs*
>> less test.hs*
#!/usr/bin/env stack
-- stack script --resolver lts-15.3
-- --package=turtle
-- --package=text
...
```
うまく生成できた．（実行もできる．）

# 参考
## stack script

* [Stackを使って楽しくHaskellスクリプティング](https://qiita.com/tanakh/items/1ca4ba9e1f5006a30106)

* [script interpreter + stack script でスクリプティング！](https://haskell.e-bigmoon.com/stack/tips/script-interpreter.html)

## turtle

* [Turtle.Tutorial](https://hackage.haskell.org/package/turtle-1.5.17/docs/Turtle-Tutorial.html)

* [Gabriel439/Haskell-Turtle-Library](https://github.com/Gabriel439/Haskell-Turtle-Library)

* [HaskellでShellみたいなことをやるのに便利なライブラリの紹介](https://qiita.com/t10471/items/70af33487ece780b6c10)