picture by ghc
Table of Contents
Learning Haskell
Haskellの本家から、おもしろい学習ページをみつけた。 Learning Haskell
これの、4. Spirals, Snowflakes & Trees: Recursion in Pictures が、今回 のターゲット。下記のお絵書きモジュールを時間をかけて入れておく。
Rasterific: A pure haskell drawing engine.
[sakae@arch pict]$ ls
CHANGELOG.md LineGraphics.hs Main.hs pict.cabal
[sakae@arch pict]$ cat pict.cabal
cabal-version: 2.4
name: pict
version: 0.1.0.0
synopsis: pict sample
homepage:
license: NONE
author: sakae
maintainer:
extra-source-files: CHANGELOG.md
library
exposed-modules: LineGraphics
build-depends: JuicyPixels >= 3.3.8,
Rasterific >= 0.7.5.4,
base ^>=4.16.4.0
default-language: Haskell2010
executable pict
main-is: Main.hs
other-modules: LineGraphics
build-depends:
JuicyPixels >= 3.3.8,
Rasterific >= 0.7.5.4,
base ^>=4.16.4.0,
pict
default-language: Haskell2010
[sakae@arch pict]$ cat Main.hs
module Main where
import Codec.Picture
import LineGraphics
house :: Path
house = [(300, 750), (300, 450), (270, 450), (500, 200),
(730, 450), (700, 450), (700, 750)]
door :: Path
door = [(420, 750), (420, 550), (580, 550), (580, 750)]
myhouse = drawPicture 5.0 [(lightgreen, house), (red, door)]
main :: IO ()
main = writePng "my.png" myhouse
[sakae@arch pict]$ cabal build Resolving dependencies... Build profile: -w ghc-9.2.7 -O1 In order, the following will be built (use -v for more details): - pict-0.1.0.0 (lib) (first run) - pict-0.1.0.0 (exe:pict) (first run) Configuring library for pict-0.1.0.0.. Preprocessing library for pict-0.1.0.0.. Building library for pict-0.1.0.0.. [1 of 1] Compiling LineGraphics ( LineGraphics.hs, /tmp/pict/dist-newstyle/build/x86_64-linux/ghc-9.2.7/pict-0.1.0.0/build/LineGraphics.o, /tmp/pict/dist-newstyle/build/x86_64-linux/ghc-9.2.7/pict-0.1.0.0/build/LineGraphics.dyn_o ) Configuring executable 'pict' for pict-0.1.0.0.. Preprocessing executable 'pict' for pict-0.1.0.0.. Building executable 'pict' for pict-0.1.0.0.. [1 of 2] Compiling LineGraphics ( LineGraphics.hs, /tmp/pict/dist-newstyle/build/x86_64-linux/ghc-9.2.7/pict-0.1.0.0/x/pict/build/pict/pict-tmp/LineGraphics.o ) [2 of 2] Compiling Main ( Main.hs, /tmp/pict/dist-newstyle/build/x86_64-linux/ghc-9.2.7/pict-0.1.0.0/x/pict/build/pict/pict-tmp/Main.o ) Linking /tmp/pict/dist-newstyle/build/x86_64-linux/ghc-9.2.7/pict-0.1.0.0/x/pict/build/pict/pict ... [sakae@arch pict]$ cabal run Up to date [sakae@arch pict]$ ls CHANGELOG.md dist-newstyle/ LineGraphics.hs Main.hs my.png pict.cabal
普通にghciを起動してしまうと、下記の様に面倒な事になる。必ず、cabal replで起動しよう。
[sakae@arch pict]$ ghci
Loaded package environment from /home/sakae/.ghc/x86_64-linux-9.2.7/environments/default
GHCi, version 9.2.7: https://www.haskell.org/ghc/ :? for help
ghci> :l Main.hs
[1 of 2] Compiling LineGraphics ( LineGraphics.hs, interpreted )
LineGraphics.hs:12:1: error:
Could not load module ‘Codec.Picture’
It is a member of the hidden package ‘JuicyPixels-3.3.8’.
You can run ‘:set -package JuicyPixels’ to expose it.
(Note: this unloads all the modules in the current scope.)
It is a member of the hidden package ‘JuicyPixels-3.3.8’.
You can run ‘:set -package JuicyPixels’ to expose it.
(Note: this unloads all the modules in the current scope.)
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
12 | import Codec.Picture
| ^^^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
ghci> :set -package JuicyPixels
package flags have changed, resetting and loading new packages...
ghci> :l Main.hs
[1 of 2] Compiling LineGraphics ( LineGraphics.hs, interpreted )
[2 of 2] Compiling Main ( Main.hs, interpreted )
Ok, two modules loaded.
ghci> :t drawPicture
drawPicture :: Float -> Picture -> Image PixelRGBA8
enjoy
cabal buildしてライブラリィーなパッケージを作成。仕様は、
library
exposed-modules: Pict, LineGraphics
build-depends: base ^>=4.16.4.0,
JuicyPixels >= 3.3.8,
Rasterific >= 0.7.5.4
こんな感じ。オリジナルでは、Fractalsとなってたけど、Pictに変更してる。 一番最初に記述したライブラリィーが親分になって、:browseに出てくるよう だ。もう一方も参照(:t xx)できるようにするには、:m + LineGraphicsってやれ ば良い。
sakae@deb:/tmp/pict$ cabal repl Build profile: -w ghc-9.2.7 -O1 In order, the following will be built (use -v for more details): - pict-0.1.0.0 (lib) (ephemeral targets) Preprocessing library for pict-0.1.0.0.. GHCi, version 9.2.7: https://www.haskell.org/ghc/ :? for help [1 of 2] Compiling LineGraphics ( LineGraphics.hs, interpreted ) [2 of 2] Compiling Pict ( Pict.hs, interpreted ) Ok, two modules loaded. ghci> :bro house :: Path door :: Path myhouse :: Image PixelRGBA8 startLineFrom :: Point -> Line -> Line connectLine :: Line -> Line -> Line scaleLine :: Float -> Line -> Line rotateLine :: Float -> Line -> Line fade :: Colour -> Colour spiralRays :: Float -> Float -> Int -> Colour -> Line -> Picture spiral :: Float -> Float -> Int -> Line -> Path polygon :: Int -> Line -> Path kochFlake :: Int -> Line -> Path kochLine :: Int -> Point -> Point -> Path fractalTree :: Float -> Int -> Line -> Path ghci> ghci> :t drawPicture drawPicture :: Float -> Picture -> Image PixelRGBA8 ghci> :t writePng writePng :: PngSavable pixel => FilePath -> Image pixel -> IO () ghci> writePng "a.png" $ drawPicture 3.0 $ spiralRays 1.0 0.95 128 green ((400,400), (400,500)) ghci> hp = pi / 2 ghci> hp 1.5707963267948966 -- 90 degree ghci> ps = spiral hp 1.01 128 ((400,400), (400, 500)) ghci> length ps 128 ghci> take 4 ps [(400.0,400.0),(400.0,500.0),(299.0,500.0),(299.0,397.99)] ghci> take 4 $ drop 64 ps [(444.52094,355.91992),(444.52094,544.9662),(253.58423,544.9662),(253.58423,352.12012)] ghci> writePng "b.png" $ drawPicture 1.0 [(green, ps)]
フラクタルツリーの例。
myline = ((470,800), (360,800)) pp = fractalTree 0.35 13 myline writePng "dol.png" $ drawPicture 2.0 [(green, pp)]
svg
svgはどうかと、haskell専用の羂索サイトで探してみる。
Hackage: The Haskell Package Repository – Search package
何はなくとも、パッケージの体裁を準備。肝心の中身はgitの例。FreeBSDの cabalだと微妙に版が進んだものを提示してきた。cabalは変化が激しくて、ネッ トの情報をそのまま鵜呑みに出来ない。手探りですな。
[sakae@fb /tmp/hoge]$ cat hoge.cabal
cabal-version: 3.0
name: hoge
version: 0.1.0.0
-- synopsis:
-- description:
license: Apache-2.0
license-file: LICENSE
-- author:
-- maintainer:
-- copyright:
build-type: Simple
extra-doc-files: CHANGELOG.md
-- extra-source-files:
common warnings
ghc-options: -Wall
executable hoge
import: warnings
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base ^>=4.16.4.0, svg-builder
hs-source-dirs: app
default-language: Haskell2010
裸のghciを使うと、ちょっと嫌味を言われる。cabal replするかemacsから使 え。要するに、xxx.cabalはMakefileなんだな。これに従って、各種のアプリ が動くようになってるって事だ。
ghci> :set -package base
package flags have changed, resetting and loading new packages...
ghci> :l app/Main.hs
[1 of 1] Compiling Main ( app/Main.hs, interpreted )
Ok, one module loaded.
ghci> main
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" width="300" xmlns:xlink="http://www.w3.org/1999/xlink" height="200" version="1.11.1"><rect fill="red" width="100%" height="100%"/><circle fill="green" cy="100" cx="150" r="80"/><text fill="white" x="150" font-size="60" y="125" text-anchor="middle">SVG</text></svg>
others
もう少しお絵書きモードを探してみる。
Haskell組み込みDSLでSVGを書く うーん FreeBSD では、コンパイルに失敗 するぞ。
diagrams – svg ? 巨大すぎるパッケージだなあ。
glossではじめるグラフィック描画 これも巨大。OpenGLだかを使うなんて、失 敗にまっしくらっぽい。
ちょいと気分転換に、 ウォークスルー Haskell see monad
xx.cabalで手抜きする方法、みみっちいな。
common shared-properties
default-language: Haskell2010
build-depends:
-- list of common dependencies
library
import: shared-properties
test-suite start-haskell-test
import: shared-properties
build-depends:
-- list of test only dependencies
Haskell/GHC symbol search cheatsheet これは、ありがたい。記号って大変 だからね。
haddocs by w3m
haskell-modeにw3mとの連携が出てたので、試してみる。
15 Browsing Haddocks using w3m
;; (setq w3m-mode-map (make-sparse-keymap))
;; (define-key w3m-mode-map (kbd "RET") 'w3m-view-this-url)
;; (define-key w3m-mode-map (kbd "q") 'bury-buffer)
;; ;(define-key w3m-mode-map (kbd "<mouse-1>") 'w3m-maybe-url)
;; (define-key w3m-mode-map [f5] 'w3m-reload-this-page)
;; (define-key w3m-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock)
;; (define-key w3m-mode-map (kbd "M-<left>") 'w3m-view-previous-page)
;; (define-key w3m-mode-map (kbd "M-<right>") 'w3m-view-next-page)
;; (define-key w3m-mode-map (kbd "M-.") 'w3m-haddock-find-tag)
(defun w3m-maybe-url ()
(interactive)
(if (or (equal '(w3m-anchor) (get-text-property (point) 'face))
(equal '(w3m-arrived-anchor) (get-text-property (point) 'face)))
(w3m-view-this-url)))
(require 'w3m-haddock)
(add-hook 'w3m-display-hook 'w3m-haddock-display)
;; (defcustom haskell-w3m-haddock-dirs
;; '("~/.ghcup/share/doc/"))
(define-key haskell-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock)
w3m-mode-mapの所が大幅にコメントしてるけど、こうしておかないと、w3mの 閲覧モードが制限されてしまうから。
また、 defcustomをイネーブルにすると、emacsに怒られたので、カスタム設定を個別 にやった。このw3mサポートは、さっぱりメンテナンスされていない。もうw3m なんてのは旧式なUIになったのか。今じゃ、猫も杓子もMS製だものな。
https://hoogle.haskell.org/?hoogle=Graphics.Rasterific
なんてのに一発で飛んで行くようにしたいな。
engine-mode こういう汎用品が有るなあ。
GHCi + Hoogle - A Guide and Thoughts ここまで、やるか? 単独コマンドの hoogleを入れるってか、コンパイルするの非常に大変そう。まあ、裏で秘密の HTTP通信をやる、アプリだからなあ。それに加えてデータベースへのアクセス もある。例えると、mysqlのクライアントだな。ArchLinuxにはコマンドが用意 されてたけど、下記で凌ぐ事にした。
;; engine-mode (require 'engine-mode) (engine-mode t) (setq engine/browser-function 'eww-browse-url) ;; C-x / h (defengine hoogle "https://hoogle.haskell.org/?hoogle=%s" :keybinding "h") ;; C-x / g (defengine google "https://www.google.com/search?ie=utf-8&oe=utf-8&q=%s" :keybinding "g")
検索文字列にカーソルを置いて、 C-x / h すれば、hoogleに飛んでくれる。おしい事に、ドットで結合されたモ ジュール名は、最左しか拾ってくれないので、適当に補ってあげる必要がある。 まあ、それぐらいは我慢しろ。ついでなんで、ググル用も用意した。
Search Hoogle (main): String -> [String] Search Hoogle: a -> [a] Search Hoogle (putStrLn):
とかが、簡単に調べられる。
ググルへの質問
Search Google: haskell ghci no need let ------ haskell ghci no need let - Google 検索: https://www.google.com/search?q=haskell+ Google haskell ghci no need let Submit すべて動画画像ニュース 地図 ショッピング 書籍 検索ツール ヒント: 日本語の検索結果のみ表示します。検索言語は [表示設定] で指定できます 5. GHCi を使う — Glasgow Haskell Compiler 8.2.2 User's Guide ghcguide.haskell.jp › users_guide › ghci GHC 8.0.1 以降 let 文を使わなくても,値や関数で名前を束縛できます. ... HaskellのソースファイルをGHCiにロードするには :load コマンドを使います. GHCi "let" -- what does it do? - haskell - Stack Overflow :
letは必須だと思っていたんだけど、ある時にそれを忘れてしまった。けど、 エラーにならず。なら楽な方が良いと思っていた。これで、お墨つきを得たな。
rust basic
ちょいと浮気して見てる。何となくhaskellの一般系に思えるぞ。 それより、楽しいH本を再読するのが先だな。なんか、螺旋状に理解が深まっ ていく感じがする。
haskellもrustで書いたら、より安全になるだろう。誰かやってみ。 型安全だけじゃ、片手落ちと思うぞ。