stack for haskell

ラズパイでマストドンなんて言う無理環境を作っている方に前回出会った。普通にラズパイを 使うと、どうなるんだろうって、色々見てたら、

KiwiSDR

ラズパイでラジオって人に出くわした。ああ、ラジオって言ったら、ラジ子は、いつまで フラッシュを使わせる積りなんだろう? 既にインフラが出来上がっているから、今更変えるって、とっても大変。と言う、企業の論理で、ユーザーに不便不安を提供するのは、いかがな ものかと。その点、あくどい視聴税の徴収で潤っている所のらじるは、おk。)

SDRなんてのが出てきたんで、瞬間的にjavaを思い出した。ある時からjavaのプラグインが 無いと、聞けなくなって、疎遠になってたんだ。

A WebSDR is a Software-Defined Radio receiver connected to the internet

久しぶりに行ってみたら、HTML5でもおkになってた。そうだよ、そうこなくっちゃ。

redis

ドッカーの説明書を見てたら、オイラーの知らないredisなんてのが出てた。MySQLとかposgresSQLと並置されてたから、DBってのは予想が付くが。。。調べてみた。

Redisの使い方

alpine:~$ redis-server --help
Usage: ./redis-server [/path/to/redis.conf] [options]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
       ./redis-server --test-memory <megabytes>

Examples:
       ./redis-server (run the server with default conf)
       ./redis-server /etc/redis/6379.conf
       ./redis-server --port 7777
       ./redis-server --port 7777 --slaveof 127.0.0.1 8888
       ./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:
       ./redis-server /etc/sentinel.conf --sentinel

サーバーを建てておいて、

alpine:~$ redis-cli
127.0.0.1:6379> set wanko bow-wow
OK
127.0.0.1:6379> get wanko
"bow-wow"
127.0.0.1:6379> set hoge 1234
OK
127.0.0.1:6379> get hoge
"1234"
127.0.0.1:6379> get *
(nil)
127.0.0.1:6379> shutdown
not connected> help
redis-cli 3.2.5 (git:c72176ef)
To get help about Redis commands type:
      "help @<group>" to get a list of commands in <group>
      "help <command>" for help on <command>
      "help <tab>" to get a list of possible help topics
      "quit" to exit

クライアントから接続するとな。適当な時間間隔で、勝手にファイルに落としてくれる。 更に特徴的なのは、データの保持時間を、データ登録時に(オプションで)設定出来る事。 これ、Webで使うと便利そう。まるで、スパイ映画に出て来る、この文書は3分後に自動 消去されますが実現されてる。

stack in clear linux

clear linuxの品揃え(bundle)を見ていると、何となく目指す方向が見えてくるような気が する。Webを作る材料の提供。特徴的なのは、機械学習もターゲットに置かれている事。 今のご時世を反映してるな。そういう理解で良いんだろうけど、haskell-basicと銘打った バンドルがこっそり潜り込んでいる。hskellもWebの仲間にどうそって事?

バンドルなんで、一発導入するだけで、haskellの開発環境が整うんだろね。昔はちまちまと アプリを入れてたけど、ドッカー対抗って事で、一発なんだろうね。どんなのがやって来るか 調べてみると、

# [TITLE]: haskell-basic
# [DESCRIPTION]: Build and run haskell language programs
# [STATUS]: Active
# [CAPABILITIES]:
# [MAINTAINER]: William Douglas <william.douglas@intel.com>
# stack ends up using gcc, make, xz, perl, libgmp, libffi and zlib
automake
gcc
gcc-dev
git
gmp-dev
libc6-dev
make
ncurses-lib
p11-kit
perl
stack
xz
zlib-dev

これだけあれば何とかなる? 肝心のghcが居ないじゃん。怪しそうなstackって、聞いた事が あるぞ。なんでも、haskellのパッケージャであるcabalが糞で、地獄を見る事になるんで、 天国目指して、stackが誠意開発中だったはず。あれ? 誠意じゃなくて鋭意だろう。 いや、悩めるハスケラーに誠意を見せるのが目的です。入れてみた。

そして、叩いてみた。さらば、開かれん。 ザーと一行説明が出て来るのは、今風の不親切。おもてなしが足りないと思うのは、日本人の オイラーだけ? いや違うな。後ろにlessをかませるのはunix流。余計な事はしない。

sakae@clr:~$ stack
stack - The Haskell Tool Stack

Usage: stack [--help] [--version] [--numeric-version] [--hpack-numeric-version]
             [--docker*] [--nix*] ([--verbosity VERBOSITY] | [-v|--verbose] |
             [--silent]) [--stack-root STACK-ROOT] [--work-dir WORK-DIR]
             [--[no-]system-ghc] [--[no-]install-ghc] [--arch ARCH]
             [--ghc-variant VARIANT] [-j|--jobs JOBS] [--extra-include-dirs DIR]
             [--extra-lib-dirs DIR] [--with-gcc PATH-TO-GCC]
             [--[no-]skip-ghc-check] [--[no-]skip-msys] [--local-bin-path DIR]
             [--[no-]modify-code-page] [--[no-]allow-different-user]
             [--resolver RESOLVER] [--compiler COMPILER] [--[no-]terminal]
             [--stack-yaml STACK-YAML] COMMAND|FILE
 :
Available commands:
 :
  ghci                     Run ghci in the context of package(s) (experimental)
  repl                     Run ghci in the context of package(s) (experimental)

そうか、stackからghciを起動出来るとな。

sakae@clr:~$ stack ghci
Run from outside a project, using implicit global project config
Using latest snapshot resolver: lts-8.15
Writing implicit global project config file to: /home/sakae/.stack/global-project/stack.yaml
 :

で、肝心のghcが無いので、setupしろとな。

sakae@clr:~$ stack setup
Run from outside a project, using implicit global project config
Using resolver: lts-8.15 from implicit global project's config file: /home/sakae/.stack/global-project/stack.yaml
 :
/usr/bin/tar: ghc-8.0.2/libraries/dph/ghc-packages: Cannot open: No such file or directory
/usr/bin/tar: Exiting with failure status due to previous errors

Error encountered while unpacking GHC with
  tar Jxf /home/sakae/.stack/programs/x86_64-linux/ghc-tinfo6-8.0.2.tar.xz
  run in /home/sakae/.stack/programs/x86_64-linux/ghc-tinfo6-8.0.2.temp/

The following directories may now contain files, but won't be used by stack:
  - /home/sakae/.stack/programs/x86_64-linux/ghc-tinfo6-8.0.2.temp/
  - /home/sakae/.stack/programs/x86_64-linux/ghc-tinfo6-8.0.2/

Unpacking GHC into /home/sakae/.stack/programs/x86_64-linux/ghc-tinfo6-8.0.2.tem

そして、DISKが溢れた。大きいんだな。残念ながら、お試し版のclearLinux環境では、試せないのか。貧乏人は辛いよ。

stack in debian

こうなったら、OSを乗り換えて、広々した所でやってみるか。最初にstackの導入からだな。

The Haskell Tool Stack

どれぐらい容量を喰うなんて説明は一切無し。都合の悪い事は隠すのが常識みたいです。 まあ、沢山DISKを消費しても、10Gはいかないだろうと言う目論見でdebianでやってみます。

[debian ~]$ curl -sSL https://get.haskellstack.org/ | sh
Detected Linux distribution: debian

Installing dependencies...
 :
以下のパッケージが新たにインストールされます:
  libffi-dev libgmp-dev libgmpxx4ldbl
 :
Stack has been installed to: /usr/local/bin/stack

WARNING: '/home/sakae/.local/bin' is not on your PATH.
    For best results, please add it to the beginning of PATH in your profile.

足りないパッケージを揃えてくれるんだな。

[debian ~]$ stack ghci
Writing implicit global project config file to: /home/sakae/.stack/global-project/stack.yaml
 :
No compiler found, expected minor version match with ghc-8.0.2 (x86_64) (based on resolver setting in /home/sakae/.stack/global-project/stack.yaml).
To install the correct GHC into /home/sakae/.stack/programs/x86_64-linux/, try running "stack setup" or use the "--install-ghc" flag.
[debian ~]$ stack setup
Preparing to install GHC to an isolated location.
This will not interfere with any system-level installation.
Downloaded ghc-8.0.2.
Installed GHC.
stack will use a sandboxed GHC it installed
For more information on paths, see 'stack path' and 'stack exec env'
To use this GHC and packages outside of a project, consider using:
stack ghc, stack ghci, stack runghc, or stack exec

やっぱり、ghcが無いんでsetupしろとな。ここで注文をだすと、古いghcでも受け付けて くれるんだろうね。で、どれぐらい喰ってるか確認。

[debian ~]$ du -sh .stack
2.2G    .stack

ほー、2.2Gってghcと各種パッケージのindex込みの容量。それに、 /usr/local/bin/stackが haskellのワールド(自分だけのね)な環境なのね。

Stackをhaskell-modeで使ってみよう

virtual BOX の Disk拡張

悔しいのでClearLinuxの入っているDiskの拡張に挑戦する。

現状はこんな感じ。GPTが使われている。

sakae@clr:~$ sudo partx -l /dev/sda
# 1:      2048-   131071 (   129024 sectors,     66 MB)
# 2:    131072- 10616831 ( 10485760 sectors,   5368 MB)

Linuxのdisk関係コマンドを漁ってみた。resizepart(8)に出てたやつ。

SEE ALSO
       addpart(8), delpart(8), fdisk(8), parted(8), partprobe(8), partx(8)

その前にバーチャルボックス側でDISKを拡張する。 VirtualBoxのゲストOSディスク拡張

無理しないで、16Gにした。

c:\work>VBoxManage.exe modifyhd --resize 16384 clear-15410-live.vdi
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

これで確認すると、現在値とDISKパラメータが異なっていると文句を言われる。

sakae@clr:~$ sudo fdisk -l /dev/sda
GPT PMBR size mismatch (10618879 != 33554431) will be corrected by w(rite).
Disk /dev/sda: 16 GiB, 17179869184 bytes, 33554432 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 1048576 bytes
Disklabel type: gpt
Disk identifier: 07FAD0D3-5D11-4CD3-9516-667A7F123611

Device      Start      End  Sectors Size Type
/dev/sda1    2048   131071   129024  63M EFI System
/dev/sda2  131072 10616831 10485760   5G Linux root (x86-64)

この状態で、パーテションを追加しても、1Mぐらいしか増えない。

色々調べてみると、DISK系のツールは、strage-utils に入っているとの事なんで、バンドルを追加した。そうしたら、partedが使えるようになった。同コマンドで、現在値を 確認しようと printって叩いたら、DISKのパラメータに齟齬が有るんで、修正するかと聞かれた。勿論、FIX(修復)してってお願いしたよ。

後は、また、fdiskの出番。

fdisk /dev/sda
  :
Device      Start      End  Sectors Size Type
/dev/sda1    2048   131071   129024  63M EFI System
/dev/sda2  131072 10616831 10485760   5G Linux root (x86-64)

Command (m for help): n
Partition number (3-128, default 3):
First sector (10616832-33554398, default 10616832):
Last sector, +sectors or +size{K,M,G,T,P} (10616832-33554398, default 33554398):

Created a new partition 3 of type 'Linux filesystem' and of size 11 GiB.

Command (m for help): p
Disk /dev/sda: 16 GiB, 17179869184 bytes, 33554432 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 1048576 bytes
Disklabel type: gpt
Disk identifier: 07FAD0D3-5D11-4CD3-9516-667A7F123611

Device        Start      End  Sectors Size Type
/dev/sda1      2048   131071   129024  63M EFI System
/dev/sda2    131072 10616831 10485760   5G Linux root (x86-64)
/dev/sda3  10616832 33554398 22937567  11G Linux filesystem

一度、再起動すると有効になると言われたので、その通りにする。そして、後は ファイルシステムを作ってマウントだな。

root@clr:~# mkfs.ext4 /dev/sda3
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 2867195 4k blocks and 718080 inodes
Filesystem UUID: 185ebe90-f6a5-4c4f-acf6-efad5bb9e1e2
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208
 :
root@clr:~# mkdir /work
root@clr:~# chmod 777 /work
root@clr:~# mount /dev/sda3 /work
root@clr:~# df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root        5095040 3448652   1367860  72% /
devtmpfs         2019760       0   2019760   0% /dev
tmpfs            2021892       0   2021892   0% /dev/shm
tmpfs            2021892     788   2021104   1% /run
tmpfs            2021892       0   2021892   0% /sys/fs/cgroup
tmpfs            2021892       0   2021892   0% /tmp
clr_debug_fuse   5095040 3448652   1367860  72% /usr/src/debug
clr_debug_fuse   5095040 3448652   1367860  72% /usr/lib/debug
tmpfs             404376       0    404376   0% /run/user/1000
/dev/sda3       11222900   40984  10592096   1% /work

文字通りworkなんで、誰でも気軽に利用できるように、パーミションは/tmp並みにしておいた。 後は、マウント情報を登録しとくだけ。

sakae@clr:~$ cat /etc/fstab
/dev/sda3   /work  auto    defaults       0 0

autoの所は、ext4でも良かったか。sda3なんてデバイスが勝手に沸いて出てくるのね。 デバイスが沸いて来るのは許せるけど、BUGが沸いてくるのは許せんな。特に蚊というBUG。 一年分の蚊への献血を一度にするから、オイラーの所に勝手に採血しに来ないでね。

リベンジするぞ

場所も出来た事なんで、再チャレンジ。debian様での施行により、俺様haskell環境が、.stackに出来上がる事を知っているので、そいつを/workの下に逃がすように、前準備しる。 そして、インストール実行。

sakae@clr:~$ mkdir /work/.stack
sakae@clr:~$ ln -s /work/.stack .stack
sakae@clr:~$ stack ghci
sakae@clr:~$ stack setup
sakae@clr:~$ stack repl
Run from outside a project, using implicit global project config
Using resolver: lts-8.15 from implicit global project's config file: /work/.stack/global-project/stack.yaml
Configuring GHCi with the following packages:
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /tmp/ghci2337/ghci-script
Prelude>

生意気にリンク先をちゃんと追跡して、報告してきたよ。そういう性格がhaskellの生き様 なのね。きっちりし過ぎて、息が詰まりそうだよ。

:? で、説明が読めるのはいいんだけど、ざーと説明が流れてしまって、前の方が確認出来ない。 パイプでlessに渡すのもセッションの中では出来ないので、ファイルに落としておいて、後で嫁ってか。おもてなしが足りないぞ。

sakae@clr:~$ stack ghci |& tee ghci.memo
Prelude> :?
Prelude> :q
Leaving GHCi.
sakae@clr:~$ less ghci.memo

screenだと、画面を遡って確認出来たんだけど、tmuxにはそういう機能が無いものかしら。 clearとかalpineとかにもtmuxはデフォで入っているんで、ちゃんと機能を調べて、使い倒して 野郎。

それとも、emacsの上でeshellを使い、バックスクロール可能な端末としちゃうかだな。 この方法が素直かもしれないな。でも、時々、eshellの上に居る事を忘れ

~/hugsBook $ emacs transmit.lhs
emacs: Terminal type "dumb" is not powerful enough to run Emacs.
It lacks the ability to position the cursor.
If that is not the actual type of terminal you have,
use the Bourne shell command 'TERM=...; export TERM' (C-shell:
'setenv TERM ...') to specify the correct type.  It may be necessary
to do 'unset TERMINFO' (C-shell: 'unsetenv TERMINFO') as well.

こんな風に、頓珍漢な怒られ方になる。いや、そういう理解は間違ってるぞ、emacs深読みを せい。馬鹿端末の上ではemacsを起動出来ないのよ。だから、環境変数のTERMとかに、xterm ぐらいは設定してねって、親切に案内してるんだ。

その通りに、vt220ぐらいな端末ですって、指定したら、emacs in emacs が実現するのだろうか? emacs深追いすると、新しい知見が得られるかも?

そんな事より、Haskellをまともに使うなら、 Haskell Modeを、しっかり見ておくと、吉。