関数型プログラミング言語Haskell Part33

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2020/02/10(月) 18:17:36.49ID:L6eYQqyh
関数型プログラミング言語 Haskell について語るスレです。

Haskell Language(公式サイト)
https://www.haskell.org/
日本Haskellユーザーグループ - Haskell-jp
https://haskell.jp/

前スレ
関数型プログラミング言語Haskell Part32
https://mevius.5ch.net/test/read.cgi/tech/1548720347/
2020/08/14(金) 06:03:07.79ID:OycuixUd
>>369
今のHaskell Platformのインストールってそういう感じになってるんだな
Chocolatey自体はWindowsでそこそこよく使われているパッケージマネージャなので一応信頼してよい
373デフォルトの名無しさん
垢版 |
2020/08/14(金) 08:46:51.97ID:XgOd4/dA
>>370
Windowsにそのままインストールしちゃいました。



Windows PowerShellから起動する以外の使い方はないでしょうか?
GHCiというのもグラフィカルユーザーインターフェースのソフトはないのでしょうか?
374デフォルトの名無しさん
垢版 |
2020/08/14(金) 12:57:45.74ID:XgOd4/dA
リストとタプルについてなんですが、Pythonでのリストとタプルとは違いがあるようです:

let a = [1,2,3]
drop 1 a

としてもa == [2,3]とはなりません。

let b = (1,2,3)
drop 1 b

とするとエラーになります。

Pythonの場合は、a = [1,2,3]に要素を追加できましたが、b = (1,2,3)にはタプルがイミュータブルであるため追加できませんでした。
ですが、b[1:]とすれば、(2,3)というタプルが得られたと思います。

どう考えればいいのでしょうか?
2020/08/14(金) 17:17:33.31ID:58KQIAkg
>>374
副作用のあるコードの書き方を見せるのは簡単だけど、関数型が初めてなら
まずはHaskellのチュートリアルを読んで関数型の考え方を出来るようになったほうがいい
2020/08/14(金) 17:46:17.87ID:XgOd4/dA
>>375
ありがとうございます。
「すごいHaskellたのしく学ぼう!」という本の第1章を読み終わりました。この本を読んでいこうと思います。
2020/08/14(金) 20:54:14.09
なぜエラーになるかといえば、タプルにdropはないからです
リストは『全て同じ型』の要素の片方向リストです。要素数は可変です。C++のforward_listをイメージしてください

タプルは『それぞれ好きな型の組み合わせ』であり、リストではありません。要素数は固定です

両者は本質的に内部実装が異なります。リストは要素と、次に辿る先の情報を組にしたデータ構造、一方でタプルはその数だけデータを納めるのみのデータ構造です

抽象的には、リストは2要素のタプルであり、一項目に要素、二項目は(再帰的に)リストを保有します。
こうすることで、二項目を見れば(リストなので)『要素と、二項目にまたリスト』が格納されています
そのリストの二項目を見れば・・・となって単方向リストが実装できている事が理解できます

タプル(,)は二項関数であるとみなせます。コンマの左側と右側に一つずつ何かを取って入れる関数です。
リストでは実際は『:』という二項関数が二項タプルと同じ役目を果たします。つまり
要素 : リスト
のように書き
(要素, リスト)
と抽象的に同じであると気づくことができます。
2020/08/14(金) 23:21:17.25ID:OycuixUd
>>374
コンパイルエラーの文章を読んでぐぐる癖をつけよう
覚えはじめの頃に出会うエラーは大抵は文法ミスか型エラーだろうから
ぐぐれば「何が悪いか」はだいたい解決する
「なぜ悪いか」はすごいHaskellあたりを読み進めていけば習得できるはず
2020/08/15(土) 17:24:00.25ID:uxgG4TyL
>>377-378
ありがとうございました。
380デフォルトの名無しさん
垢版 |
2020/08/16(日) 18:14:55.92ID:tHIsB9jz
Haskellの本を読んでいると静的型付けだとか出てきます。
単にHaskellの仕様を理解するだけでなくもっと深く、どういう考え方でHaskellというプログラミング言語が設計されたのかにも興味があります。
プログラミング言語論みたいな本でおすすめの本はないでしょうか?
2020/08/16(日) 21:18:57.26ID:EuDMb00g
Haskellはある日突然に誕生したわけではなく、
その前身のMirandaとKRCという関数型言語から
多くの特質を受け継いでいます
これら言語に関してはW*k*p*d*aで簡潔に解説されてるので、
まずそちらを一読したのちに参考文献に当たるべきでしょう
以下ではW*k*p*d*aで欠けている日本語の文献を紹介します

Miranda
[1] 第7章 Miranda, p139-163,
 新しいプログラミング・パラダイム, 共立出版, 1989年
 ttps://www.am*z*n.c*.j*/dp/4320024931
 Mirandaに関する包括的な解説
[2] 関数プログラミング, 近代科学社, 1991年
 ttps://www.am*z*n.c*.j*/dp/4764901811
 Mirandaを用いた関数型プログラミングの入門書
 モナドを含む圏論の応用/発展が誕生する以前の時代に書かれた貴重な教科書

KRC
[3] 4. 関数型言語 KRC, p36-47,
 新世代プログラミング, 共立出版, 1986年
 ttps://www.am*z*n.c*.j*/dp/4320022599
[4] 6.2 KRC (Kent Recursive Caluculator), p132-142,
 プログラミング言語の新潮流, 共立出版, 1988年
 ttps://www.am*z*n.c*.j*/dp/4320023773
 [3], [4] ともKRCに関する包括的な解説
 KRCはすでにインデントベースの構文/純粋関数型/ パターンマッチ/リスト内包表記
 といった特質を備えた動的型付け関数型言語でした
2020/08/16(日) 21:54:00.05ID:jqjR96Dg
>>380
まず、Types and programming languages とSteve Awodey の Category Theory 読んでからや。

Haskell の話するのは。
2020/08/16(日) 22:04:09.80ID:mrCar2cd
Haskellは魔窟の巣窟や 近寄るものは内臓から食い散らかされるデー

初心者はPythonが最適やろ〜
2020/08/17(月) 17:36:03.87ID:CFLjXFs2
>>381-382
ありがとうございました。

Types and programming languagesというのが比較的新しい本なので、興味を持ちました。
2020/08/17(月) 18:54:59.27ID:CFLjXFs2
クイックソートを行う関数を作ったのですが、エラーが出ます。どこが間違っていますか?

quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) = (quicksort [t | t <- xs, t <= x]) ++ [x] ++ (quicksort [t | t <- xs, x < t])
2020/08/17(月) 19:01:32.08ID:QJrG17W6
>>385
Haskell初心者に限った事柄ではないけれど、
こうした場で質問する者の心構えとして
出てしまったエラーメッセージをコピペする
といった、当たり前の行動は身につけるべきだと思うよ
2020/08/17(月) 19:03:19.26ID:CFLjXFs2
>>386
ありがとうございます。
エラーメッセージは以下です。

Prelude> :r
[1 of 1] Compiling Main ( baby.hs, interpreted )

baby.hs:153:1: error:
parse error (possibly incorrect indentation or mismatched brackets)
|
153 | quicksort :: (Ord a) => [a] -> [a]
| ^
Failed, no modules loaded.
2020/08/17(月) 19:05:47.77ID:CFLjXFs2
インデントも間違っていないと思いますし、カッコも問題ないと思うのですが。
2020/08/17(月) 20:38:28.08ID:0Q701Csj
>>388

>>385 をコピペしたら、俺の環境では動いたよ。
取り急ぎ。
2020/08/18(火) 02:46:50.61ID:rj5JRKyz
153行より前の部分がおかしいんでしょ
2020/08/18(火) 10:50:34.85ID:QANbTDtx
>>389-390
ありがとうございました。
>>390
ご指摘どおりでした。ありがとうございました。
392デフォルトの名無しさん
垢版 |
2020/08/19(水) 15:58:22.36ID:FHOhxH/M
(1)と(2)で同じ関数だそうです。

add :: Int -> Int -> Int

add :: Int -> (Int -> Int)
と等価だそうです。

だとするならば、

(1)のほうが理屈の分かる書き方のように感じます。
(2)はadd' :: Int -> Int -> Intであると宣言しておきながら、その中身の表現を見ると、2つのInt型の引数を受け取ってその和を返す関数にしか見えません。
それにもかかわらず、add' 1は1引数の関数で引数に1を足す関数を表しています。非常に違和感を覚えるのですが、(2)は一体どういうことなのでしょうか?
わかりにくいです。

(1)
add :: Int -> Int -> Int
add n = \x -> x + n
(2)
add' :: Int -> Int -> Int
add' n m = n + m
393デフォルトの名無しさん
垢版 |
2020/08/19(水) 15:59:38.45ID:FHOhxH/M
単なる表現方法と割り切ればいいのでしょうか?
394デフォルトの名無しさん
垢版 |
2020/08/19(水) 16:07:34.77ID:FHOhxH/M
nに対して、「mにn+mを対応させる関数」を対応させる関数の表記法として、
add' n m = n + m
を採用するというのが非常に不自然に思います。
2020/08/19(水) 16:24:31.96ID:amUamLwq
入門書のカリー化の箇所を読めばいいんじゃね
haskell内での関数は一変数関数として扱えて、
add' n m = (add' n) m
というだけ
396デフォルトの名無しさん
垢版 |
2020/08/19(水) 16:31:52.13ID:FHOhxH/M
>>395
ありがとうございます。
(1)の表記法だけ許してほしいと思うんです。(2)だけみたらまるで2変数関数のように見えますから。
2020/08/19(水) 20:35:34.21ID:1ghAy1sC
(今は結合性と優先順位は無視していいので)
n + m

(+) n m
と同じ意味になる。

つまり(2)は
add = (+)
に変数を明示して右辺の演算子を中置記法に戻しただけ

むしろ変数増やしたのが見にくい原因
2020/08/20(木) 07:58:20.18ID:mQjEXV61
>>392
(1) の展開は中途半端で、ちゃんと書くならこう

(0)
add :: Int -> Int -> Int
add = \n -> \m -> n + m

これを(1)や(2) のように書いてもよいというのはHaskellの決め事
慣れないうちは常にこう書いていてもよいが
書くのも読むのも段々面倒になってくると思う
慣れればあまり意識せずに読み替えられるので

ついでに言うと
真の2変数関数が必要ならタプルを用いてこう書く
add'' :: (Int, Int) -> Int
add'' (n, m) = n + m

これらは確かに厳密には区別しなくてはいけないが、
ゆるく同一視しておくほうが便利なことも多いので
Haskellでは(2)のような書き方が許されている、と自分は理解している
2020/08/20(木) 08:57:36.69ID:LuBKaaMH
>>397-398
ありがとうございます。
>>398
(0)
add :: Int -> Int -> Int
add = \n -> \m -> n + m
この書き方が本質的で一番わかりやすいですね。
ありがとうございます。
400デフォルトの名無しさん
垢版 |
2020/08/20(木) 11:51:35.78ID:LuBKaaMH
圏論入門 Haskellで計算する具体例から
雪田修一 (単行本)

図書館に購入リクエスト済みです。楽しみです。
401デフォルトの名無しさん
垢版 |
2020/08/20(木) 14:53:48.13ID:uVfTx7sc
>>1 simulationライブラリで純粋な関数式プログラミングをする ttp://x0000.net

学術の巨大掲示板群 - アルファ・ラボ ttp://x0000.net
数学 物理学 化学 生物学 天文学 地理地学
IT 電子 工学 言語学 国語 方言 など

VM + ASM を書いた (C#, DX) * x86 ではない!
simulationライブラリで純粋な関数式プログラミングをする
UIライブラリ (C#, 2D) を作ったよ
連続と離散を統一した!
4Dエンジン
matrixのライブラリ
ある強力なFor関数
SQLライブラリ

VM + ASM のダウンロード
ttp://up.x0000.net/files/TSimulang.zip
402デフォルトの名無しさん
垢版 |
2020/08/21(金) 10:45:55.90ID:VIa1N6p8
関数の合成をする関数(.)を以下のように誤って書きました。
(x -> f (g x))はラムダ関数なので(\x -> f (g x))と書かないといけないと思います。
ですが、以下のコードでちゃんと動作しました。なぜでしょうか?

(.) :: (b -> c) -> (a -> b) -> a -> c
. = \g -> f -> (x -> f (g x))
403デフォルトの名無しさん
垢版 |
2020/08/21(金) 11:35:07.30ID:VIa1N6p8
あともう一つ質問があります。

「すごいHaskellたのしく学ぼう!」に「関数合成は右結合なので、一度にたくさんの関数を合成できます。f (g (z x))は(f . g. z) xと等価です。」
と書いてありますが、左結合だったとしても、同様に一度にたくさんの関数を合成できるはずです。
左結合だったとしてもf (g (z x))は(f . g. z) xと等価であることに変わりはないはずです。

これは一体何が言いたいのでしょうか?
2020/08/21(金) 18:51:58.39ID:3Xa4QDEo
>>403
左結合だと等価にならないよ
2020/08/21(金) 18:53:55.87ID:VIa1N6p8
(f . g) . z = f . (g . z)だから等価だと思ったんですけど、間違っていますか?
2020/08/21(金) 20:51:03.06ID:3LvfPoDL
通常の関数適用は左結合だから
f g z x は ((f g) z) x と同じ意味になって
コンパイルエラーになっちゃうけど
関数合成演算子を使うと括弧が減るよ、ということが言いたいはず

関数合成自体は結合的だからそこの向きは確かに関係ないね
2020/08/21(金) 22:34:08.88ID:nqLClnr+
>>403
単純に
>f (g (z x))は(f . g. z) xと等価です。
は、数学と同じ優先順位ですよってことじゃない?
それ以上の疑問は抱かんかったけど

試してないけど、俺も>>404に同意
多分整数演算で除算演算の関数を関数合成すれば、いくつか試せば同一にならないのは簡単に見つかるはず
引数をたくさん試すだけでも見つかりそう めんどこっいのでやらないけど
2020/08/21(金) 23:19:07.20ID:nqLClnr+
>>405
それってそうなの?

俺は、数学の本好きで読んでるんだけど、そこまで基本的なことは突き詰めてないw
写像の合成が結合則を満たす ものもたくさんありそうだけど、
写像の合成は必ず結合則を満たすものなの?そこから疑問に思った方がいいんじゃない?
数学の本読んでると、右XXと左XXと区別するものが多いんで、普通に満たさないと思ってたw
いや、俺が間違ってるかもしれんから、そこから調べてくれると俺もうれしい

ちなみに、大学数学レベルなのが 1+1=2 の証明。俺は調べたくないw
2020/08/22(土) 00:32:18.31ID:75MjfSAz
>>408
位相空間論の入門書には大抵書いてあるよ
あと「Haskellによる関数プログラミングの思考法」にも(証明は無いが)言及があった

((f . g) . h) x
= (f . g) (h x)
= f (g (h x))
= f ((g . h) x)
= (f . (g . h)) x

この等号は計算結果が等しいという意味で
途中の時間・空間計算量の違いは気にしていないので念の為
2020/08/22(土) 00:48:03.06ID:66roH7xF
>>408
しらんけど、位相空間って連続写像仮定してないか?
プログラミング言語でいう写像とは違う
位相空間論で一般的に言われているのならその定理を示した方がいいんじゃない?
個人的には位相空間論の書籍に限定しているのが気になる。どちらかと言うと代数学の方が一般的と思うが。

>あと「Haskellによる関数プログラミングの思考法」にも(証明は無いが)言及があった
こっちはたぶん書籍持ってるかな?ページ数教えてくれる?
四則演算というか群論でいう、逆元を仮定しているとかそんな感じやない?しらんけど

数学ではよくあるけど、仮定が大事 それを無視するから、結論を間違えるのはよくある
貴方が間違えたかどうかは知らんど
写像の合成で結合則が必ず成り立つのなら、そのような記述はどっかの書籍に必ずある
自分は見たこと無い。あるとすれば、なんらかの仮定で限定されている。
2020/08/22(土) 01:01:19.51ID:fPcZe606
知らん過ぎ
2020/08/22(土) 01:40:43.87ID:75MjfSAz
>>410
> 個人的には位相空間論の書籍に限定しているのが気になる。どちらかと言うと代数学の方が一般的と思うが。
位相空間論の〜っていうのは言い方が悪かったかな、「集合と位相」みたいなタイプのやつ
大抵最初の方で一般の集合論をやるのでそういうつもりで言った

仮定が大事というのはその通りで
もちろん連続性も全単射も仮定しない一般の写像に対する定理

集合A, B, C, D と写像 f: C->D, g: B->C, h: A->B に対して
(f . g) . h = f . (g . h) が成り立つ

> >あと「Haskellによる関数プログラミングの思考法」にも(証明は無いが)言及があった
> こっちはたぶん書籍持ってるかな?ページ数教えてくれる?
P.30 第1章 練習問題Eの解答
こっちはあまりにも簡素に書いてあるので見ても何の参考にもならないかもだが…

ただしHaskellには全域でない関数があるから(headとかtailみたいな例外を返し得るやつね)
そういうのが絡むと結合性が怪しいケースはもしかしたらあるかもしれない
2020/08/22(土) 12:23:17.90
ここ三年以内に発売されたハスケルの本は?
414デフォルトの名無しさん
垢版 |
2020/08/22(土) 13:18:34.82ID:g0O87mtN
空気読まずに有限集合でやってみる。

``` code
#{-# LANGUAGE ExistentialPython #-}
import math;
import random;
import string;
def none ():
dot = lambda bc, ab: {a : bc [b] for a, b in ab.items ()};
make_map = lambda a, b: dict (zip (a, random.choices (b, k = len (a))));
A = tuple (range (5));
B = random.sample (string.ascii_lowercase, 10);
C = random.sample (string.ascii_uppercase, 8);
D = (math.nan, math.inf, None, (), 'hello', 'world');
ab = make_map (A, B);
bc = make_map (B, C);
cd = make_map (C, D);
assert dot (cd, dot (bc, ab)) == dot (dot (cd, bc), ab);
return ((A, B, C, D), (ab, bc, cd));
out = none ();
```

自分の知る限り、素朴な写像の描像が描けないガジェットに対して「写像」という
言葉は使わないので、写像が結合的かどうかという議論に意味があると思えない。
415デフォルトの名無しさん
垢版 |
2020/08/22(土) 13:19:16.92ID:g0O87mtN
``` code
#{-# LANGUAGE FunctionalJupyter #-}
import IPython.display as display;
def none (node, edge):
f = lambda col, a: {key : (row, col) for row, key in enumerate (a)};
nodes = {};
for val in [f (j, a) for j, a in enumerate (node)]: nodes.update (val);
edges = [];
for xy in edge: edges += [(nodes [x], nodes [y]) for x, y in xy.items ()];
node_out = r"""<text class='clazz' x='{x}' y='{y}'>{z}</text>""";
edge_out = r"""<line class='clazz' x1='{x_0}' y1='{y_0}' x2='{x_1}' y2='{y_1}'/>""";
out = '';
w, h, dw = 100, 20, 20;
for key, val in nodes.items (): out += node_out.format (x = w * val [1], y = h * val [0], z = key);
for a, b in edges: out += edge_out.format (x_0 = w * a [1] + dw, y_0 = h * a [0], x_1 = w * b [1] - dw, y_1 = h * b [0]);
style = r"""<style> text.clazz { dominant-baseline: middle; text-anchor: middle; } line.clazz { stroke: black; fill: none; } </style> """.strip ();
svg = f"""<svg width='400' height='300' viewBox='{-20} {-20} {len (node) * w + 20} {max (map (len, node)) * h + 20}'>{out}</svg>""";
display.display (display.HTML (style + svg));
return None;
none (*out);
```
416デフォルトの名無しさん
垢版 |
2020/08/22(土) 13:31:18.86ID:DGMheHKA
それで?
会話や食事の中の唾液飛沫の3次元シミュレーションが出来るんですか?
417デフォルトの名無しさん
垢版 |
2020/08/22(土) 13:35:02.20ID:j3K8XBr1
>>402
あれ、これ今日コンパイルしたらエラーが出た。
単にコンパイルしていなくて、ghciで用意されている(.)を使ってテストしていただけみたいです。

以下の合成関数のコードはおそらく正しいと思います。
comp :: (b -> c) -> (a -> b) -> a -> c
comp = \f -> \g -> (\x -> f (g x))
418デフォルトの名無しさん
垢版 |
2020/08/22(土) 13:36:18.12ID:j3K8XBr1
圏論入門 Haskellで計算する具体例から (日本語) 単行本 ? 2020/8/19
雪田 修一 (著)

この超人気の本を読んだ人いますか?
419デフォルトの名無しさん
垢版 |
2020/08/22(土) 13:41:29.64ID:j3K8XBr1
>>417
この関数の書き方を一度書いたら、
func a b = …
みたいな書き方は気持ち悪くて嫌になりますね。
420デフォルトの名無しさん
垢版 |
2020/08/22(土) 13:45:41.47ID:j3K8XBr1
すごいHaskell、やっと5章まで読み終わりました。
この辺りから難しくなりますか?
421デフォルトの名無しさん
垢版 |
2020/08/22(土) 21:29:49.29ID:YtG8IJDk
難易度竹。
422デフォルトの名無しさん
垢版 |
2020/08/22(土) 21:45:32.55ID:j3K8XBr1
すごいHaskellの6章を読んでいますが、いきなり難しくなりました。

find :: (a -> Bool) -> [a] -> Maybe a
のMaybe aというのは探している要素が見つからなかった場合に返されるNothingが属するような型を用意したかったからですか?
423デフォルトの名無しさん
垢版 |
2020/08/22(土) 21:46:48.62ID:j3K8XBr1
もしそうだとして、質問なんですが、Nothingはあらゆる型に属すると約束すればいいだけの話ではないんですか?
2020/08/23(日) 07:53:38.79ID:m55Vd3Cb
「null安全」でググれ
かつて、あらゆる型に属するnullを導入していた言語が、
nullのない型を別途導入する方向に動いている
425デフォルトの名無しさん
垢版 |
2020/08/23(日) 10:09:34.95ID:ts+Zp8he
ヌルポはどこにバグがあるかを教えてくれるが、
ボトポにはそれさえない。

``` code
bottom :: a
bottom = bottom

dangerous_find :: (a -> Bool) -> [a] -> a
dangerous_find _ [] = bottom
dangerous_find pred (a : as) = if pred a then a else dangerous_find pred as
```

ただ役に立たないというだけでなく、
危険なほど役に立たない関数も作りたければ作れる。
2020/08/23(日) 11:59:38.54ID:PT3WAMjf
>>403
これ、左結合が出来ないからじゃない
考え方としては左結合はありなんだろうけど、
実質無いということ

f.g.h x で左結合やろうとしても、

関数適用と合成の優先順位で関数適用の方が優先される
結果として右結合にしかならない。
427デフォルトの名無しさん
垢版 |
2020/08/23(日) 12:29:03.24ID:hbFjgy0U
学術の巨大掲示板群 - アルファ・ラボ ttp://x0000.net
数学 物理学 化学 生物学 天文学 地理地学
IT 電子 工学 言語学 国語 方言 など

VM + ASM を書いた (C#, DX) * x86 ではない!
simulationライブラリで純粋な関数式プログラミングをする
UIライブラリ (C#, 2D) を作ったよ
連続と離散を統一した!
4Dエンジン
matrixのライブラリ
ある強力なFor関数
SQLライブラリ

VM + ASM のダウンロード
ttp://up.x0000.net/files/TSimulang.zip
428デフォルトの名無しさん
垢版 |
2020/08/23(日) 13:32:54.91ID:41ZiKAKU
>>426
「関数合成は、一度にたくさんの関数を合成できます。f (g (z x))は(f . g. z) xと等価です。」
だったら、違和感がないんですが、
「関数合成は右結合なので、一度にたくさんの関数を合成できます。f (g (z x))は(f . g. z) xと等価です。」
には違和感を感じます。

一度にたくさんの関数を合成できる理由が関数合成が右結合だからというのはやはりおかしいと思います。
2020/08/23(日) 13:36:29.73ID:41ZiKAKU
Function composition is right-associative, so we can compose many functions at a time.
The expression f (g (z x)) is equivalent to (f . g . z) x.

これが原文です。翻訳がおかしいわけではないようですね。
2020/08/23(日) 13:53:55.24ID:PT3WAMjf
関数適用を合成より優先順位上げる条件のもと
合成を左結合でλ式に落とし込こんでみればいいんじゃない

出来るのなら俺の間違い 出来ないのなら
左結合では合成が出来ないのだから、文章も間違ってない

と思っただけ
2020/08/23(日) 16:12:09.03ID:ZATaa76b
>>428
確かに俺も疑問に思ってた
結局何が言いたいんだ?ってなってそのまま放置してたわ
432デフォルトの名無しさん
垢版 |
2020/08/23(日) 16:16:46.30ID:41ZiKAKU
>>424
ありがとうございました。検索してみようと思います。

>>425
ちょっと何を言っているのか分かりませんでした。
433デフォルトの名無しさん
垢版 |
2020/08/23(日) 23:06:04.74ID:ts+Zp8he
ごめん、関係ないと書いておくべきだった。
今後は、自分の投稿は全て無視して欲しい。
誰かの質問に答えているつもりはなくて、
プログラミングのネタを拾っているだけ。

ついでなので、前回のペーストビンにアップしたネタについて書く。

まず、タプル、状態、継続以外の随伴はちゃんとしていない。
アウェイの圏をちゃんと書こうとすると泣きが入る。Haskellは集合の圏では
超強力だが、それ以外の圏に対しては並になる。中は見てないが、
[species](https://hackage.haskell.org/package/species)では、
圏をほぼフルスクラッチで作っているんじゃないかと思う。
で、コードにする段階でウソをついているのだが、素直にウソをつけば、
上手く行くことがあるということがあそこで得た教訓。

あそこに書いたモナドでパラメーター対象を2つ持つモナドは全て`R p (L p a)`
という形をしているが、コードでは型宣言を省略しているので、結局、
非対角成分を含めた`R p (L q a)`という形の関手についてのKleisli合成が
得られている。それがレンズが出てきた理由の一つ。
書いたときは知らなかったのだが、非対角成分を含めた関手を
[インデックスモナド](https://stackoverflow.com/questions/28690448/what-is-indexed-monad)
というらしい。パラメーター対象をもつ随伴からKleisli合成を計算すれば、
自然とインデックスモナドになってしまう。ただし、圏論プロパーに
インデックスモナドと言っても通じないと思う。Haskellでの専門用語だと思う。
434デフォルトの名無しさん
垢版 |
2020/08/25(火) 10:01:02.60ID:d4SFWo3v
Data.Mapについて質問です。

キーがOrd型でないといけないという制約があります。

これは、Mapの実装でキーのデータ構造がハッシュではなく、2分探索木のようなものだからでしょうか?
2020/08/25(火) 18:47:32.02ID:NgJQjBWI
>>434 ドキュメントにそれっぽいことが書いてあるけど
https://hackage.haskell.org/package/containers-0.6.3.1/docs/Data-Map-Strict.html

> The implementation of Map is based on size balanced binary trees (or trees of bounded balance) as described by:

> If you don't care about ordering, consider use Data.HashMap.Strict from the unordered-containers package instead.
2020/08/25(火) 20:49:35.22ID:d4SFWo3v
>>435
ありがとうございました。
2020/08/27(木) 10:07:06.62ID:TufIdPw/
Jupyter NotebookでHaskell使うならこれ
環境構築の手間が省けるのでおすすめ
Chromebook、iPad、Windows 10 Sモードなどで使えるかは知らない
https://mybinder.org/v2/gh/gibiansky/IHaskell/master

IHaskell
https://github.com/gibiansky/IHaskell
> You can now try IHaskell directly in your browser at CoCalc or mybinder.org.
Alternatively, watch a talk and demo showing off IHaskell features.
2020/08/27(木) 11:10:22.56ID:sFui1x5L
やっぱ最近新しい言語勉強するときはjupyter note book重宝する
2020/08/28(金) 11:44:03.31ID:8bIwySwM
ついにメンテのされてないgladeが最新のghcじゃビルドできなくなった
シコシコGUI作るの面倒くさくて意気消沈
2020/08/28(金) 12:26:16.24ID:5nZNKLNm
はすけらはjs嫌いだろうけど(偏見)elmかpurescriptなら使えるだろ
2020/08/28(金) 12:57:36.50ID:lCzdfIoX
デスクトップGUIアプリの大半はWebブラウザアプリで代替できる。
これを機に、一度こだわりを捨ててみるのも良いかも。
442デフォルトの名無しさん
垢版 |
2020/08/28(金) 13:05:48.93ID:LLs1s+XQ
Webブラウザアプリの大半はデスクトップGUIアプリの方が使い易い。
2020/08/28(金) 14:56:59.18ID:5nZNKLNm
だよな。はすけらならpurescriptでelectronだよ。
2020/08/28(金) 15:48:19.78ID:jEdLmLEr
pureselectか
2020/08/28(金) 16:04:05.32
書いて三日以内のコードをビルドしました
2020/08/30(日) 11:24:16.79ID:uCpf8zkM
質問です
次のプログラムが走りません
Ratio Integer型の割算です
mainの最後の行を受け付けてくれません

import Data.Ratio
import Data.Complex

(///) (x:+y) (z:+w) = let
d = z^2 + w^2
in ((x*z-y*w)/d):+((x*w+y*z)/d)

x :: Ratio Integer
x = 1%1
y = 3%1
z = 2%1
w = 4%3

main = do
print $ (x:+y) /// (z:+w)
print $ x / (z^2+w^2)
print $ (x:+y) /// ((z:+w) + (x:+y))
2020/08/30(日) 11:24:49.92ID:uCpf8zkM
エラーメッセージは以下です
何がダメかどなたかわかりませんか?

Haskell Online Compiler [ghc-8.4.4]
Copyright (c) The University of Glasgow

Compiling your program...

[1 of 1] Compiling Main ( prog.hs, prog.o )

prog.hs:23:25: error:
• No instance for (RealFloat (Ratio Integer))
arising from a use of ‘+’
• In the second argument of ‘(///)’, namely ‘((z :+ w) + (x :+ y))’
In the second argument of ‘($)’, namely
‘(x :+ y) /// ((z :+ w) + (x :+ y))’
In a stmt of a 'do' block:
print $ (x :+ y) /// ((z :+ w) + (x :+ y))
|
23 | print $ (x:+y) /// ((z:+w) + (x:+y))
| ^^^^^^^^^^^^^^^
2020/08/30(日) 11:27:13.14ID:uCpf8zkM
あ、11行目は
in ((x*z-y*w)/d):+((-x*w+y*z)/d)
でした
でも同じエラーメッセージ出てきます
何故でしょう?
2020/08/30(日) 14:19:38.49ID:ubwYKL6u
>>446
自己レスです
もしかしてこの型制限ですかね?

RealFloat a => Num (Complex a)

Complex a型がNumクラスに入れるのはaがRealFloat型の時しかダメだからでしょうか?
この制限はなんでこんなにキツイんだろ
足したり引いたりしたいだけなのに
2020/08/30(日) 15:28:05.73ID:0W5gc2Gs
>>449
自作のComplexクラスをNum型クラスのインスタンスにしてみようとすると気づくんだけど
Numってなぜかabs関数を実装しないといけないんだよね
それで複素数の妥当な絶対値関数を書くにはsqrtが必要だけど
Numだと計算できないので…という理屈のはず

Haskellの標準の数値型に対する不満はちょくちょく見かけるけど
歴史的経緯もあって現状はしょうがないということになってるはず
2020/08/30(日) 15:32:06.86ID:mGp/4vHZ
>>449
https://downloads.haskell.org/~ghc/latest/docs/html/libraries/base-4.14.0.0/src/Data-Complex.html
でData.ComplexのソースコードでNumクラスのインスタンス定義を見たところ
メソッドabsとsignumの実装に
magnitude :: (RealFloat a) => Complex a -> a
を使ってるからみたいだね

本当に足したり引いたりしたいだけならNum制約は強すぎる
数のクラス体系の問題点について詳しくは
https://blog.miz-ar.info/2016/06/haskell-num-class/
2020/08/30(日) 17:39:55.49ID:z5he+9Sw
>>450
>>451
ありがとうございます
まぁabsが必須ならしょうがないですね
なんか考えます
2020/08/31(月) 00:20:32.36ID:XlY0VH6O
Complex RationalにNumのinstance宣言できないかと思って以下のようにしてみました

instance Num (Complex Rational) where
(x:+y) + (x':+y') = (x+x') :+ (y+y')
(x:+y) - (x':+y') = (x-x') :+ (y-y')
(x:+y) * (x':+y') = (x*x'-y*y') :+ (x*y'+y*x')
negate (x:+y) = negate x :+ negate y
abs z = undefined
signum z@(x:+y) = undefined
fromInteger n = fromInteger n :+ 0

結果以下のようにそれは無理と怒られます
何かてはないでしようか?

Haskell Online Compiler [ghc-8.4.4]
Copyright (c) The University of Glasgow

Compiling your program...

[1 of 1] Compiling Main ( prog.hs, prog.o )

prog.hs:7:10: error:
• Illegal instance declaration for ‘Num (Complex Rational)’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for ‘Num (Complex Rational)’
|
7 | instance Num (Complex Rational) where
| ^^^^^^^^^^^^^^^^^^^^^^
2020/08/31(月) 11:01:46.76ID:rDcCtqL6
知らんけどコンパイラの言う通りFlexibleInstances使ったら?
2020/08/31(月) 13:16:55.43ID:m1GQ7XMv
意味も分からずコンパイラの指示に従ってばかりいても、
初心者の域は抜けられない

でも、コンパイルできなきゃモチベーションが下がるから、
取りあえず従っとけ
2020/08/31(月) 17:00:23.04
でた!おまじない!
2020/08/31(月) 17:10:43.28ID:rDcCtqL6
標準のhaskellだと

instance 型クラス 型構築子
instance 型クラス (型構築子 型変数1)
instance 型クラス (型構築子 型変数1 型変数2)


って形式のインスタンス宣言にしか対応してないからな

instance 型クラス (型構築子 型構築子)

って書きたいなら言語拡張使えって言われる

言語拡張使うか、あるいは、もっと一般的なインスタンス宣言
instance Num a => Num (Rational a)
とかにしたら?
2020/08/31(月) 18:26:13.20ID:mkAi3PX1
皆さんご助言ありがとうございます
実は家のパソコン壊れててHaskellはオンラインHaskellコンパイラというので当座を凌いでるんですがコレコンパイラオプションもインラインプラグマ?とかいうのも使えないっぽくてFlexible Instanceとか使いたくても使えないんです
Num Rationalは標準で入ってます
入れられなくて困ってるのはNum (Complex Rational)なんです
Num a=>Num (Complex a)
は二重定義でダメだと怒られます

prog.hs:55:12: error:
Duplicate instance declarations:
instance Num a => Num (Complex a) -- Defined at prog.hs:55:12
instance RealFloat a => Num (Complex a)
-- Defined in ‘Data.Complex’
|
55 | instance Num a => Num (Complex a) where
| ^^^^^^^^^^^^^^^^^^^^^^^^
2020/08/31(月) 18:28:35.47ID:mkAi3PX1
しょうがないのでとりあえずComplex Rationalを“カプセル化”してみました
複素座標0,3,4i,7/2+7/2iである4点が同一円周上にあるか確認するプログラムです
同じ事をComplex Floatとかでやると丸め誤差で誤判定してくれます
できるんですがちょっと不愉快ですね
2020/08/31(月) 18:28:47.62ID:mkAi3PX1
import Data.Ratio
import Data.Complex

data ComplexRational = CR (Complex Rational) deriving (Show,Eq)
instance Num (ComplexRational) where
(CR (x:+y)) + (CR (x':+y')) = CR $ (x+x') :+ (y+y')
(CR (x:+y)) * (CR (x':+y'))
= CR $ (x*x'-y*y') :+ (x*y'+y*x')
negate (CR (x:+y)) = CR $ negate x :+ negate y
abs = undefined
signum = undefined
fromInteger n = CR $ fromInteger n :+ 0
instance Fractional (ComplexRational) where
recip (CR (x:+y))= CR $ (x/(x^2+y^2)):+(-y/(x^2+y^2))
toComplex (CR x) = x

i = CR $ 0:+1

onCircle a b c d = (==0) $ imagPart $ toComplex $ ((a-c)/(b-c))/((a-d)/(b-d))

a=0
b=3
c=4*i
d=7/2+7/2*i

main = do
print $(1/2+3/4*i)/(5/6+7/8*i)
print $ onCircle a b c d

-----
CR (618 % 841 :+ 108 % 841)
True
2020/09/03(木) 16:35:31.39ID:VDk3Uebh
すごいHaskell、7章を読んでいますが、正直、重要ではあるが面白くない内容なので読むペースが遅くなってしまっています。
最後まで読み切ろうと思います。
462デフォルトの名無しさん
垢版 |
2020/09/03(木) 16:55:07.23ID:VDk3Uebh
図書館にリクエストした以下の本を買ってもらうことができて、明日、借りられることになりました。
楽しみです。

圏論入門 Haskellで計算する具体例から
雪田 修一 (著)
2020/09/04(金) 20:26:41.82ID:zDdu0cA6
雪田著『圏論入門』を借りてきました。
圏論、難しい上につまらないです。
2020/09/04(金) 20:35:32.88ID:4VK1Z/Kj
何を期待して借りたのやら
2020/09/04(金) 21:42:59.80ID:W/y0jTmz
圏論はモナドへの近道
2020/09/05(土) 02:01:31.05ID:hzZ7uEzq
>>458
です
自己レスです
色々調べて一応Complex RationalにNumのinstance入れる方法見つけました
しかしかなり裏技というか、あまり関心しない方法かもしれません
やはり正攻法は>>460のようにカプセル化する方だと思いますけど、せっかく見つけたのでうpします
>>460と同じく0,3,4i,7/2+7/2iが同一円周上にあるか確認するプログラムです
ついでにabsも使えるようにしてあります
absがいらないならsqrt=の部分がなくても動作します
2020/09/05(土) 02:03:13.00ID:hzZ7uEzq
import Data.Ratio
import Data.Complex

instance (Integral a)=> Floating (Ratio a) where
sqrt = fromRational.toRational.sqrt
.fromRational.toRational
instance (Integral a) => RealFloat (Ratio a) where
floatDigits = floatDigits.fromRational.toRational
decodeFloat = decodeFloat.fromRational.toRational
scaleFloat k x = if k > 0 then x*2^k else x/2^(-k)
2020/09/05(土) 02:03:23.39ID:hzZ7uEzq
i = 0:+1%1

onCircle a b c d = id
$ (==0)
$ imagPart
$ ((a-c)/(b-c))/((a-d)/(b-d))

(a,b,c,d)=(0,3,4*i,7/2+7/2*i)

main = do
print $(1/2+3/4*i)/(5/6+7/8*i)
print $ onCircle a b c d
print $ ((a-c)/(b-c))/((a-d)/(b-d))
print $ abs $ 2+3*i
print $ abs $ 15+8*i
----
618 % 841 :+ 108 % 841
True
4 % 7 :+ 0 % 1
8118979690322419 % 2251799813685248 :+ 0 % 1
17 % 1 :+ 0 % 1
2020/09/05(土) 13:15:04.05ID:T3msgi7J
純粋に興味のみからすごいHaskellを読んでいるのですが、みなさんはなぜHaskellを使っているのですか?
2020/09/05(土) 13:35:41.51ID:EwmIpy36
宣言的に書けた時の気持ち良さがたまらんから
2020/09/05(土) 14:03:13.58ID:T3msgi7J
>>470
やはり実用よりは趣味ということですね。
2020/09/05(土) 14:05:39.74ID:14+GNjHV
Haskellで書かれた実用的なアプリ無いからな。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況