recipe-collection icon indicating copy to clipboard operation
recipe-collection copied to clipboard

コンテンツ中の haskell コードを自動でコンパイルする。

Open kayhide opened this issue 7 years ago • 7 comments

このあたりを使えば何かしらできそうな気配がします。

kayhide avatar Apr 03 '17 11:04 kayhide

仕組みとしては、Travis-CIとかを使えばいいのかもしれませんね。

工夫のしどころはコンテンツを

  1. Markdownファイル(foo.md)として書いて、そこにコードブロックを埋め込む
  2. Haskellスクリプトファイル(foo.hsまたはfoo.lhs)として書いて、説明はコメントとして埋め込む のどちらにするかで考え方が違ってくると思います。

基本的には、1. の場合は解説が主で、コードは説明のための具体例、2. の場合はコードが主で、解説はコメントと考えることになります。

そのうえで、1. の場合は、コードの抽出と抽出したコードの実行の仕組みに工夫がいりそうですね。2. の場合は、文書としてはHaddockで処理してHTMLでみる程度でよければ全体をパッケージにするとそのまま利用可能なので結構便利かも。

TFwHのサイト はTravis-CIとは未連携で未完成ですが 2.の考え方でサイトを構成しています。 自動コンパイルの仕組みは設定していませんが、master はHaskellスクリプトで構成しておいて gh-pagesをstack haddockで生成したhtmlで構成するようにしてます。 tfwhパッケージ はパッケージとしての汎用性はないですが、 コードはすぐに試せるようになってます。

nobsun avatar Apr 03 '17 13:04 nobsun

@nobsun コメントありがとうございます。

仕組みとしては、Travis-CIとかを使えばいいのかもしれませんね。

そうですね。 それができればバッヂも使えるのでサンプルコードの健全性はひと目でわかるようにできそうです。 Haskell で ci ツールを回したことはありませんけど、依存パッケージを大量に使ってたりしても大丈夫なのかな?

基本的には、1. の場合は解説が主で、コードは説明のための具体例、2. の場合はコードが主で、解説はコメントと考えることになります。

このレシピ集では、メンテナビリティを重要な視点として考えています。 いってみればコンテンツを陳腐化させない、というのがミッションですね。 そのために、編集コストはできるだけ下げたいですし、閲覧者が気付いたらすぐにツッコミいれれるような仕組みにもっていきたいです。

いま、1. の方針ではじめているのはそういう背景にもとづいています。 markdown だと前提知識は(haskell や haddock に比べて)少なくて済みますし、github 上でいきなりコンテンツになっている、という手軽さを活用しようとしています。

とはいえ、パッケージにする、という発想はなかったので面白いですね。

コンテンツは markdown のまま何とかしてパッケージにする、というのはさすがにムリでしょうか?

kayhide avatar Apr 03 '17 14:04 kayhide

コンテンツは markdown のまま何とかしてパッケージにする、というのはさすがにムリでしょうか?

markdown から有効なコードブロックだけを抽出して、モジュールファイルに変換するツールがあれば、 masterブランチのリポジトリを処理してcodeブランチ(名前は適当)を構成する仕組みが作れそう。

自動化の具体的な方法はよく判っていないですがなんとかなるかも。

nobsun avatar Apr 04 '17 02:04 nobsun

markdown から有効なコードブロックだけを抽出して、モジュールファイルに変換するツールがあれば、 masterブランチのリポジトリを処理してcodeブランチ(名前は適当)を構成する仕組みが作れそう。

おお、それができればやりたいですね!

kayhide avatar Apr 04 '17 02:04 kayhide

markdown から有効なコードブロックだけを抽出して、モジュールファイルに変換するツール

これには https://hackage.haskell.org/package/markdown-unlit というパッケージがあります。ただしdoctestのようにghciのセッションとしてテストする機能はないので、必要であれば自作する必要があります。

maoe avatar Apr 04 '17 03:04 maoe

markdownからコードブロックを抽出できるライブラリがあるのであれば、

  • src/template/article0001.md
    • 記事本文
  • app/Article.hs
    • Hakyllなどを使って実際の記事を生成
  • src/Codes/Article0001.hs
    • article0001.md 内のコードをTHで展開してコンパイルできるようにする
    • 記事ごとにファイルを用意することで、記事ごとに依存ライブラリが異なる問題や、関数名の衝突を防げる
  • app/Code.hs
    • src/Codes/*.hs をよみこむ

みたいにすれば、記事の生成(app/Article.hs)とコードが正しいかどうかのチェック(app/Code.hsがコンパイルできるかどうか Travisとかでチェック)が同時にできそうですね!

main関数をコードブロックで定義することも想定するとTHで展開した結果に対してエラーがでないように、 THで展開する際に適当にmainmain0などにリネームすることも必要だと思います。

実際には人力でコードをチェックしたほうが結果的にはコストが低いとは思いますが、 このプロジェクト自体がHaskellの魅力を体現することになるのであれば、こういう仕組みを導入してもいいかもしれないですね!

arowM avatar Apr 04 '17 05:04 arowM

REPLの実行例が書いてあるmarkdownについて似たようなことやったんですが、そのときは、

https://github.com/sol/doctest/blob/master/ghci-wrapper/src/Language/Haskell/GhciWrapper.hs

をコピペしてきて使いました(publicじゃないので)。

REPLじゃない通常のsnippetはファイルに切り出して :l で読ませました。こうしておくと、記事中で関数などを定義した snippet を出した後に、直後にそれを REPL から使うという解説の仕方をしている場合にも検証ができて便利でした。

hiratara avatar Apr 05 '17 14:04 hiratara