ghcup

Table of Contents

ghcup

Stackでプロジェクト管理

とほほのHaskell入門

お気楽 Haskell プログラミング入門

Haskellの環境構築2023

haskell-platformを入れるのは古いんか。debianで試してみる。

sakae@deb:~$ curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
  :
[ Error ] [GHCup-00841] Process "gmake" with arguments ["DESTDIR=/home/sakae/.ghcup/tmp/ghcup-c7512e80",
[ ...   ]                                 "install"] failed with exit code 2.
[ Error ] Also check the logs in /home/sakae/.ghcup/logs
"ghcup --metadata-fetching-mode=Strict --cache install ghc recommended" failed!

libtinfo5 を入れたのだけど相変わらずエラー。これはひょっとして、 /usr/lib/i386-linux-gnu/libtinfo.so.5と言う、debian方言な場所が悪いと 判断。/usr/libに再配置。この処置でOKになった。

最後に、こんなアドバイスがあった。

All done!

To start a simple repl, run:
  ghci

To start a new haskell project in the current directory, run:
  cabal init --interactive

To install other GHC versions and tools, run:
  ghcup tui

If you are new to Haskell, check out https://www.haskell.org/ghcup/steps/

at FreeBSD

ghcupはサポートされていない。pkgからghcを入れておく。hs-cabal-installを入れる と、cabalが使えるようになる。cabal updateすると、.cache/cabalが作成さ れて、1G近いDBが作成される。大きい事は良い事なのか? もう少しなんとか ならないものか脳。

一応試運転。まずは、プロジェクトの作成だな。

[sakae@fb ~]$ mkdir myu; cd myu -- 石ちゃん風に、マイウーとかする。
[sakae@fb ~/myu]$ cabal init
What does the package build:
   1) Library
 * 2) Executable
   3) Library and Executable
   4) Test suite
Your choice? [default: Executable]
Project category:
 * 1) (none)
   2) Codec
   3) Concurrency
   4) Control
   5) Data
   6) Database
   7) Development
   8) Distribution
   9) Game
  10) Graphics
  11) Language
  12) Math
  13) Network
  14) Sound
  15) System
  16) Testing
  17) Text
  18) Web
  19) Other (specify)
 :
[Info] You may want to edit the .cabal file and add a Description field.

[sakae@fb ~/myu]$ tree
.
├── CHANGELOG.md
├── LICENSE
├── app
│   └── Main.hs
└── myu.cabal

色々な質問がされて、結果がmyu.cabalに反映される。次は、emacsの起動。勿 論、haslell-modeを入れて設定しとく。

[sakae@fb ~myu]$ emacs app/Main.hs
C-c C-l
C-x b *myu*
Restarting process ...
The lambdas must flow.
If I break, you can:
  1. Restart:           M-x haskell-process-restart
  2. Configure logging: C-h v haskell-process-log (useful for debugging)
  3. General config:    M-x customize-mode
  4. Hide these tips:   C-h v haskell-process-show-debug-tips
λ>  main
Hello, Haskell!

C-c C-lで、ロードとコンパイルが実行される。したら、プロジェクトのウィ ンドウに移動して、mainを走らせてみる。

次は、 change source and C-c C-c

Compiling: Main (app/Main.hs)
Linking: /usr/home/sakae/myu/dist-newstyle/build/i386-freebsd/ghc-9.2.7/myu-0.1\
.0.0/x/myu/build/myu/myu
Complete: cabal build (0 compiler messages)
No compiler messages, dumping complete output:
Build profile: -w ghc-9.2.7 -O1
In order, the following will be built (use -v for more details):
 - myu-0.1.0.0 (exe:myu) (first run)
Preprocessing executable 'myu' for myu-0.1.0.0..
Building executable 'myu' for myu-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /usr/home/sakae/myu/dist-new\
style/build/i386-freebsd/ghc-9.2.7/myu-0.1.0.0/x/myu/build/myu/myu-tmp/Main.o )
Linking /usr/home/sakae/myu/dist-newstyle/build/i386-freebsd/ghc-9.2.7/myu-0.1.\
0.0/x/myu/build/myu/myu ...

λ> :r
[1 of 1] Compiling Main             ( /home/sakae/myu/app/Main.hs, interpreted \
)
Ok, one module loaded.
Collecting type info for 1 module(s) ...
λ> main
Hello, Haskell! and emacs

積極的にコンパイルしてから、モジュールをリロードして、結果を確認。

3895  4  Is+  0:03.34 /usr/local/bin/cabal repl --ghc-option=-ferror-spans
3928  4  I+   0:00.79 /usr/local/lib/ghc-9.2.7/bin/ghc -B/usr/local/lib/ghc-9.2

一度起動すると、バックに居座るんだな。そして、こんな所にも残滓が。。

[sakae@fb ~/.local/state/cabal/store/ghc-9.2.7/package.db]$ ls
package.cache           package.cache.lock

with emacs

最低限な設定。

;; haskell
(add-hook 'haskell-mode-hook 'haskell-indentation-mode)
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
(add-hook 'haskell-mode-hook 'haskell-decl-scan-mode)
(add-hook 'haskell-mode-hook 'haskell-doc-mode)
(defadvice inferior-haskell-load-file (after change-focus-after-load)
  "Change focus to GHCi window after C-c C-l command"
  (other-window 1))

cabal is cargo ??

どうも、ghcupってrustupの模倣じゃなかろうか? どちらが先かは知らないけ れど。ghcは裏方で、cargoに対するcabalなんだな。ユーザーはこれだけに注 視してればよさそう。詳しい事は、

Welcome to the Cabal User Guide

sakae@deb:~$ mkdir foo
sakae@deb:~$ cd foo
sakae@deb:~/foo$ cabal init -i
Should I generate a simple project with sensible defaults? [default: y] y
cabal: The name foo is already in use by another package on Hackage.

ゆくゆくはパッケージに登録宜しくって事みたいで、商標は先願主義なんだな。

sakae@deb:~$ mkdir myfoo
sakae@deb:~$ cd myfoo/
sakae@deb:~/myfoo$ cabal init -i
Should I generate a simple project with sensible defaults? [default: y] y

Guessing dependencies...

Generating LICENSE...
Warning: unknown license type, you must put a copy in LICENSE yourself.
Generating CHANGELOG.md...
Generating src/MyLib.hs...
Generating app/Main.hs...
Generating myfoo.cabal...

Warning: no synopsis given. You should edit the .cabal file and add one.
You may want to edit the .cabal file and add a Description field.
sakae@deb:~/myfoo$ tree
.
├── app
│   └── Main.hs
├── CHANGELOG.md
├── myfoo.cabal
└── src
    └── MyLib.hs

debianでも一応確認

sakae@deb:~/myfoo$ cabal run
Resolving dependencies...
Build profile: -w ghc-9.2.7 -O1
In order, the following will be built (use -v for more details):
 - myfoo-0.1.0.0 (lib) (first run)
 - myfoo-0.1.0.0 (exe:myfoo) (first run)
Configuring library for myfoo-0.1.0.0..
Preprocessing library for myfoo-0.1.0.0..
Building library for myfoo-0.1.0.0..
[1 of 1] Compiling MyLib            ( src/MyLib.hs, /home/sakae/myfoo/dist-newstyle/build/i386-linux/ghc-9.2.7/myfoo-0.1.0.0/build/MyLib.o, /home/sakae/myfoo/dist-newstyle/build/i386-linux/ghc-9.2.7/myfoo-0.1.0.0/build/MyLib.dyn_o )
Configuring executable 'myfoo' for myfoo-0.1.0.0..
Preprocessing executable 'myfoo' for myfoo-0.1.0.0..
Building executable 'myfoo' for myfoo-0.1.0.0..
[1 of 1] Compiling Main             ( app/Main.hs, /home/sakae/myfoo/dist-newstyle/build/i386-linux/ghc-9.2.7/myfoo-0.1.0.0/x/myfoo/build/myfoo/myfoo-tmp/Main.o )
Linking /home/sakae/myfoo/dist-newstyle/build/i386-linux/ghc-9.2.7/myfoo-0.1.0.0/x/myfoo/build/myfoo/myfoo ...
Hello, Haskell!
someFunc
sakae@deb:~/myfoo$ cabal run
Up to date
Hello, Haskell!
someFunc

tails

前回見た資料で使われてたもの。

GHCi, version 9.2.7: https://www.haskell.org/ghc/  :? for help
ghci> ghci> :l tails.hs
[1 of 1] Compiling Main             ( tails.hs, interpreted )
Ok, one module loaded.
ghci> tails "abc"
["abc","bc","c"]
ghci> :r
[1 of 1] Compiling Main             ( tails.hs, interpreted )
Ok, one module loaded.
ghci> tails "abc"
["abc","bc","c",""]
tails :: [a] -> [[a]]
tails [] = [[]]
tails xs = xs : tails (tail xs)

bld

過去にhgusなりghcをやってなかったか、調べてみた。

アプリの改修

hugs -> ghc

2017年と2015年にやってたね。隔世の感がするな。歴史は繰り返します。

[sakae@fb ~]$ cabal install --lib csv
Resolving dependencies...
Build profile: -w ghc-9.2.7 -O1
In order, the following will be built (use -v for more details):
 - csv-0.1.2 (lib:csv) (requires download & build)
Downloading  csv-0.1.2
Downloaded   csv-0.1.2
Warning: csv.cabal:22:38: version operators used. To use version operators the
package needs to specify at least 'cabal-version: >= 1.8'.
Configuring csv-0.1.2...
Preprocessing library for csv-0.1.2..
Building library for csv-0.1.2..
[1 of 1] Compiling Text.CSV         ( Text/CSV.hs, dist/build/Text/CSV.o, dist/build/Text/CSV.dyn_o )
Installing library in /home/sakae/.local/state/cabal/store/ghc-9.2.7/incoming/new-23487/home/sakae/.local/state/cabal/store/ghc-9.2.7/csv-0.1.2-b84835d3167e0e42996450cf35d8754bb43bc26c4b5b66cade27d8f83a7e54d7/lib
[sakae@fb ~]$ ls .cache/cabal/
logs/     packages/
[sakae@fb ~]$ ls .cache/cabal/packages/hackage.haskell.org/
01-index.cache         colour/                primitive/
01-index.tar           csv/                   quickcheck-io/
01-index.tar.gz        data-array-byte/       random/
01-index.tar.idx       hackage-security-lock  root.json
01-index.timestamp     haskell-lexer/         snapshot.json
HUnit/                 hspec/                 splitmix/
QuickCheck/            hspec-core/            tf-random/
ansi-terminal/         hspec-discover/        timestamp.json
ansi-terminal-types/   hspec-expectations/
call-stack/            mirrors.json
[sakae@fb /tmp]$ ghci
Loaded package environment from /home/sakae/.ghc/i386-freebsd-9.2.7/environments/default
GHCi, version 9.2.7: https://www.haskell.org/ghc/  :? for help
ghci> :m + Text.CSV
ghci> :bro
type CSV :: *
type CSV = [Record]
type Field :: *
type Field = base-4.16.4.0:GHC.Base.String
type Record :: *
type Record = [Field]
csv :: parsec-3.1.15.0:Text.Parsec.String.Parser CSV
parseCSV ::
  base-4.16.4.0:GHC.IO.FilePath
  -> base-4.16.4.0:GHC.Base.String
  -> base-4.16.4.0:Data.Either.Either
       parsec-3.1.15.0:Text.Parsec.Error.ParseError CSV
parseCSVFromFile ::
  base-4.16.4.0:GHC.IO.FilePath
  -> ghc-prim-0.8.0:GHC.Types.IO
       (base-4.16.4.0:Data.Either.Either
          parsec-3.1.15.0:Text.Parsec.Error.ParseError CSV)
parseCSVTest ::
  base-4.16.4.0:GHC.Base.String -> ghc-prim-0.8.0:GHC.Types.IO ()
printCSV :: CSV -> base-4.16.4.0:GHC.Base.String

mybook

ちまちまと集めてきたhaskell関連本を開陳してみる。

7つの言語 7つの世界

表題通り7つの言語が解説されてる。1言語を3日かけて習得しましょって趣旨。 3日目にモナドが出てくるんだけど、そこで挫折。難易度最高。諦めてscalaに でも手を出してみるか?

プログラミング Haskell

Hugs時代に書かれた教科書の翻訳物。今でも十分に通用する。

Programming in Haskell こちらが原書。掲載されてるコードがDLできる。

すごいH本

随分な省略だな。Learn You a Haskell for Great Good! が、原書。 ありがたい事に、コードをコピペできる。オィ、

RWH

Real World Haskell こちらもコピペが。。。

関数プログラミング実践入門

色々な言語とhaskellを比較しながら説明してくれてるのが嬉しい。 また、実際に何個かのアプリを最初から作成し、それを改良してみせてくれる のも大変参考になる。これが、実践の由縁だな。

others

雑草という名前の草は無いって叱られそうだけど、もう1冊。

https://www.yesodweb.com/book

コードが参考になりそう。 但し、Webのフレームワークだけどね。必ずWEB用の奴は出てくるな。それだけ 需要が有るって事か。

doc

.ghcupがとても巨大なので中身を精査してたんだ。そしたらドキュメントを 発見した。これは閲覧してみる鹿。バーチャルBOX内の出来事なので、 Windowsに用意してるfirefoxを使いたい。そんな事もあろうかと、ポート フォワーディングをしてる。8080 -> 80番ね。

[sakae@arch ~]$ cd .ghcup/share/doc/ghc-9.2.7/html/
[sakae@arch html]$ python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

http://windowsip/ でOK。そして、Data.Mapを選択。最上部のバーから、 quick Jumpをクリック。ポップアップした羂索窓で、lookupを指定。 lookup,lookupLT,lookupGTとか、色々と候補が出てきた。木なんで、こういう 事が出来るのね。勉強になるなあ。で、Justなlookupに飛んでみる。そしたら、こんな例が出てきた。

import Prelude hiding (lookup)
import Data.Map

employeeDept = fromList([("John","Sales"), ("Bob","IT")])
deptCountry = fromList([("IT","USA"), ("Sales","France")])
countryCurrency = fromList([("USA", "Dollar"), ("France", "Euro")])

employeeCurrency :: String -> Maybe String
employeeCurrency name = do
    dept <- lookup name employeeDept
    country <- lookup dept deptCountry
    lookup country countryCurrency

main = do
    putStrLn $ "John's currency: " ++ (show (employeeCurrency "John"))
    putStrLn $ "Pete's currency: " ++ (show (employeeCurrency "Pete"))

これをファイルに転写して、ghciで評価。

λ>  main
John's currency: Just "Euro"
Pete's currency: Nothing

素のghciの本領発揮。rubyシステムのirbならぬ、GHCシステムのghciです。尚、 cabal ghciは、プロジェクトを建てた時に使うものだ。

rustのエコシステム

今迄のrustは事ある毎に、レポジトリィーをアクセスしていた。回線が細い上 に、コンテンツが巨大。とってもイライラ。文句が出たんでしょうね。 最近は、下記のお呪いをする事で、解消されるようになった。

sakae@deb:~/.cargo$ cat config.toml

[registries.crates-io]
protocol = "sparse"

haskellも見慣らって欲しいぞ。


This year's Index

Home