関数型プログラミング言語Haskell Part31©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
関数型プログラミング言語 Haskell について語るスレです。
haskell.org (公式サイト)
https://www.haskell.org/
前スレ
関数型プログラミング言語Haskell Part30
http://mevius.2ch.net/test/read.cgi/tech/1484491434/ >>752
ソートすれば、隣同士の要素の同値関係を調べるだけでよくなるから。
n個の要素を持つ未ソートリストの場合、
リストの第0要素を第1要素と、第2要素と・・・第n要素と比較する。
次にリストの第1要素を第2要素と・・・第n要素と比較する。
とやって、結局 O(n^2) の計算量が必要になる。
ソートするなら O(n log n) で済む。
と思ったけど、オレ勘違いしてるかな。
すまん、修理に出したPCがまだ帰ってこず、
試して速度比較できる環境にないんだ。 >>750
それも結局 O(n log n) だよね?
これが効率的には限界? >>755
アンカー間違えた。
>>753
それも結局 O(n log n) だよね?
これが効率的には限界? 一般的に同値関係とは推移律が成り立ってる関係のことを言うので
全ての要素に対して先頭の要素と同値関係が成り立つのなら任意の要素間で同値関係が成り立つ
ちなみにソートして全探索を早く打ち切らせるテクニックのことは貪欲法という dictionary云々はハッシュ関数で非可逆圧縮してからバケットソートするようなもの
バケットソートはO(n) >>757
なるほど、推移律ね、失念してた。
>>758
バケットソートは分かるが、問題はどうやってハッシュ値を求めるかだよね。
難しそうだが、考えてみる。
みんなありがと。 Arch LinuxのHaskellのリポジトリが
1年間メンテされずに死んでいる状態なのを見ると
Haskellもいよいよ落ち目だなと感じる そういう問題ではなく
向こうでHaskellへの関心が薄れているという事を言いたかった
メンテしていた人もHaskell離れしたかなとか想像できてしまう 本邦では昨年、Qiitaでのアドベントカレンダーは、HaskellがGoについで投稿数が多かった。 入門記事を読んだ人が入門記事を書いての繰り返しですやん。 >>764
数えたがアドベントカレンダーに限ってはそういうのは10個くらいだった。
120程の記事のうちで ネットでは大手のHaskell導入報告が続いて沸いてるとこだがお前らどんだけ情弱だよ Haskell使ってはいけないような低学歴知恵遅れが
Haskellに興味をもってるからな
低学歴知恵遅れがHaskell触ってはいけない
ヤバイことがおきる サイモンペイトンジョーンズがFacebookいってたけどさ、
バック→Haskell
フロント→React
みたいな構成ってそんなメジャーなんやろか FacebookはちょっとしたツールをHaskellで作ってますよ、位だと思ってたが…
>>766
> 大手のHaskell導入報告が続いて沸いてる
気づかなかった。他にはどこが? MonadIO は抽象度が高くて万能すぎ、オーバースペックだよ。
そのせいで、関数の中で何やってるのかシグネチャからは分かりにくいし。
ということで、もっと細かく分けようぜ、という話。
https://chrispenner.ca/posts/monadio-considered-harmful
簡潔で分かりやすい。
こういうのパターンっていうのかな。 githubを見る限りではとても盛り上がっているとは・・・
https://github.com/trending?l=haskell
相変わらず○○をHaskellで書いてみました系のプログラムばかり なんてことないfizzbuzzもHaskellで書くと楽しくなっちゃうんだよな
初めてプログラムを書いたときのwkwkを思い出させてくれる、それがHaskell Haskellでfizzbuzzをやろうとすると「数値か文字を出力する関数ってどうやるんだ?」
みたいなところでつまづきがち >>772
似たようなことはpurescriptではデフォルト(だった?) 結局は書く人本人が気持ちよくなる為の言語だね
パフォーマンスに優れるとかもないし 遅延ストリームを扱うならHaskellは速い方だろう
fizzbuzzの規模じゃそれを採用する利点はわからないけど むしろ最速の言語になってほしい。
「Haskellは参照透明性が保証されているために、最適化にアグレッシブになることができる。
そのため、高いコンポーザビリティによってコードは短くなるにもかかわらず、実行速度はあらゆる高級言語の中で最速である」 「Haskellは参照透明性を保証するために、最適化を犠牲にした。
そのため、高い冗長性によってコードは短くなるにもかかわらず、実行速度はあらゆる高級言語の中で鈍速である」 >>784
returnとpureのこと言ってんの?
returnとpureのこと言ってんのーーーーッ!!? コンパイラフレンドリーに記述したときの速度に概ね不満はないけどコードからパフォーマンスが予測しづらいのがね
そのコードにパフォーマンス上の問題がないか測定してみないとわからない
適切に最適化がかかるかとかスペースリークがないかとか >>787
ベテランになれば実用上問題ない程度には予測できるようになるんじゃね?
俺はまだまだ修行不足だけど 遅延評価だけでなくガベコレの遅さも問題視されるだろう(予測)
ガベコレやめてオブジェクトの寿命を予測できるレベルなら遅延評価も予測できそうだが Haskellはコンパイルさえ通ればバグは滅多にないが通説になっているけど
実際に使うと想定していた100倍くらいメモリを使っていたりと
原因特定が面倒なミスは激減するという程でもないよね。 メモリがないならディスクを使えばいいかもね
ファイルに保存できた方が原因特定も楽だし 評価順序とスペースリークは他の言語にはないバグだから逆に増えてるところもある
しかも発見しづらい
サンクのサイズが一定量に収まるかとかIOの評価順序が正格かとかって静的に解析できそうな気がするができんもんかね データベース的な仕組みだとスペースリークを放置しているやつが多い
某OSのレジストリとか くだらない質問で悪いけど質問させてほしい
Haskellでの優先順位について
・演算子の優先順位の記述はある
・関数適用の優先順位の記述はある
でも、関数の優先順位の記述が見当たらないんだけど(どっかに、左結合ってのはみた)
関数の優先順位はどうなるの?
要するに、かっこ付けの順番なんだけど
1.関数適用
2.演算子
3.関数 <= 最下位の優先順位でいいの? 不確かだけど、F#ではそのような記述があった 希ガス 795だけど、質問がうまくまとまってない希ガス
演算子と関数というのがあるけど、演算子も関数と見なしていいんだよね
ていうことは、
まず、第一の疑問は
1.関数適用の優先順位が高いとして、沢山ある関数(演算子も含む)の中でどの順番で行うのか?
第二の疑問として
3.関数 の優先順位は何?
例えば、compfunc = funcA . funcB (3 + 4)があった場合、最初の関数適用にfuncAと後ろの(.)が
が選ばれない理由でもいいかも a b c d e fの並びは(((((a b) c) d) e) f)
このa,b,c,d,e,fが関数だとか値のバインドだとか関係ない
そういう話ではない? 演算子を関数としてみなすなら
compfunc = funcA . funcB (3 + 4)
は関数として展開して
compfunc = (.) funcA (funcB ((+) 3 4))
で
compfunc = (((.) funcA) (funcB (((+) 3) 4)))
だよね >>797
それを真としすると
自分の理解では、a : funcA b:(.) c: funcB d:(3+4)となるけど、
実際の計算は(((((a b) c) d) e) f)とあってないと思う。
compfunc = funcA . funcB . funcC (3 + 4)の方が分かりやすかったかもしれないけど
関数合成は (funcA . (funcB . funcC)) (3+4)だから (つまり関数合成は右結合)
(((((a b) c) d) e) f)になってないと思う。 (関数というか、カリー化は左結合) >>798
>>799は無視してください。こっちの方が本質だから
うん、その場合なぜ、
funcAより、(.)を関数適用の優先順位を上げたのかが
自分の疑問といってもいいと思う
関数適用の優先順位が高いのはいいとして、
じゃあ、どの関数から関数適用をするの?というのが、私の疑問 >>796
演算子と関数とは似ているように思うかもしれないがちゃんと区別したほうがいい
まず関数適用とは雑に言えば項の間の半角スペースのこと
関数とか定数とか(ただし演算子は除く)をスペースでくっつけるのが関数適用
その関数適用の結合はカッコを除いて最優先なので、特に全ての演算子に優先する
(結合の仕方は>>797の通り)
そして
(.) :: (b -> c) -> (a -> b) -> a -> c
は慣れないうちは紛らわしいが、単に関数を引数に取る2項演算子なので
(演算子として使う限りは)関数適用より優先順位が低い
うーんいまいちちゃんと説明しきれてないし用語の使い方もアヤシイので
誰か詳しい人頼む haskellの構文のBNFを見てみればいいんでない? 質問です。
正確には覚えてないんですが、Haskell の型宣言を省略した場合、コンパイラ、インタプリタがよきにはからってくれてなるべく適用範囲が広い型をつけてくれます。
でもそれは Top-Level ではダメって制約があったと思うんですが、この制約なんか名前ついてたとおもうんですがなんでしたっけ?
これなんの為にあるんでしょう?
これ外すための GHC のオプションがあった記憶もあるんですがわかります?
数年ぶりに Haskell つかったら昔とったハズの杵柄がボロボロに orz。 >>799
compfunc = funcA 1 2 . funcB 4 5 . funcC 5 6 $ funcD 7 8
とあったとき、まず演算子を越えずに関数適用
compfunc = ((funcA 1) 2) . ((funcB 3) 4) . ((funcC 5 ) 6) $ ((funcD 7) 8)
このあとで演算子の優先順位で計算
>自分の理解では、a : funcA b:(.) c: funcB d:( 3+4)となるけど、
a:(.) b:funcA c:(funcB (3 + 4)) だよ
そして a:funcB b: (3 + 4)
そして a:(+) b:3 c :4
演算順序を決める丸括弧は展開出来ないよ 300行近くあるコードなんですが
Haskellの書き方としてイケてない書き方あったら教えてもらえたら嬉しいです
BASIC言語風のインタプリタです
https://csacademy.com/code/4vUVk5c9/ なんとなくわかったというか 暫定でわかった
要するに”関数適用の優先順位は高い”なんだろうね
関数の優先順位の記述が無いのは、そのようなルールが不要だと思えばいいわけで。
かっこ付けのやるべき順序として
1.関数適用 部分適用が出来るなら強欲に
2.演算子の優先順位と結合性でかっこ付け
これで、かっこ付けが終わったので、シグネチャとの整合性を取ってみる。
あっていなければ、コンパイラーエラー
ということで、コンパイラーも理解出来そうなルールになっていそうだし、
>>806とも整合性が取れそうかな BNF見ればちゃんと分かる
https://www.haskell.org/onlinereport/haskell2010/haskellch3.html
単純化するなら
exp = exp1 | exp1 op exp
exp1 = exp2 | exp1 exp2
exp2 = var | (exp)
二項演算子の優先順位を実現するには別の処理が必要だけど
少なくとも関数適用と二項演算子の計算が並ぶことはない >>810
それが、関数適用とどう関係があるのか、俺には理解できない
とうとう俺もBNFを勉強するときが来たようだw
数年に1度、思い出したようにBNFがネックになるんだけどね
今まで避けてきたw >>811
どの言語をやるにしても、ちゃんとした理解には必要になるから頑張れ >>807
イケてるかどうかなんて個人の好き嫌いだよ。
あなたの中に、こういう感じのコードは好きだけど、こういうのは嫌いというのがあって、
その基準に照らして好きなコードになっていたら、それはあなたの中ではイケてるコード、
嫌いなコードになっていたら、あなたの中ではイケてないコードということだ。
そして、好き嫌いの基準は人それぞれ、千差万別なんだよ。
他人の好き嫌いに無理に合わせる必要はない。
それを踏まえた上で、敢えて俺の好き嫌いを言うと、
俺は見通しが良くて、メンテしやすくて、発展させやすいコードが好きだ。
(宣言的ならなお良い)
だから、
・pureな計算とimpureなアクションを別の関数として分けているコードは好き。
分けていないコード大っ嫌い。
・高凝集度で低結合度なコードは好き。
逆は嫌い。
・1つの小さな仕事をさせている関数は好き。
いくつもの仕事をさせて肥えている関数は大嫌い。
・1つの役割だけをしっかり果たしているモジュールは好き。
ごった煮モジュールは大嫌い。
この基準でいくと、あなたのコードはまったくイケてない。 >>813
あざっす!勉強になりやした!精進しやす! >>813
そういうコードの設計センスはどうやって学んだのですか? >>815
大半はHaskell関係なくて、設計論の話 テストどうすんべとか、保守どうしようとか、合成できるようにしたいとか
考えるとええんやで(こなみ) +が正格で:が正格じゃないということの意味を教えてください。 stack の lts-12.x にはなぜ Yampa パッケージがないんだろ?
11.x の頃はあったのに。 stackでhp2prettyってどうやってインストールするの? >>822
stack install hp2pretty
でいける >>823
ありがと。
ヘルプ見て、stack install == stack build --copy-bins って
カレントディレクトリのプロジェクトをビルドしてできた
実行ファイルをコピーするコマンドだと思いこんでた。 以前の GHC.Stats モジュールには GCStats 型がありましたが、
GHC 8,4,1 からは廃止され、代わりに RTSStats 型および GCDetails 型になったみたいです。
そこで質問です。
以前の currentBytesUsed 関数は今で言うとどの関数に対応、あるいは近いのでしょうか。
gcdetails_live_bytes 関数でしょうか。 f :: a -> b -> c
このコロン以降の部分って、英語圏の人は何て発音してるの?
"a to b to c" で良いの? 不自然かな? 英語圏のコミュニティで日本人なんだけど。。。って質問した方が早いのでは。。。 a arrow b arrow c
call a, b, and c 漫画と同じだろ
台詞は発音するが絵は発音しない
a b c以外は発音しない みんなありがと。
よう分からんから、自分を信じて "a to b to c" って言っておくわ。
>>828
べつに日本語で読まなくてもいいと思うが。
英語でいいんじゃね? それって、そもそも発音する場面なんてあるか?
って意味じゃ・・・
つか、無理にtoで読むとして
f::(a->b)->(a->c)
はどう読むつもりだよ 身近にハスケルの話しできる人なんかいないから発音したこと無いぜ Haskell使って仕事してる人に聞いてみるしかないな c9のhuttonとmeijerのlectureでは、huttonが a to b、meijerが
a arrow bだったと思うけど、別の呼び方しても誰もなんとも思わないよ
モデル上ではcurry化なんて考える必要ないから、数式のまま
f of a and b to c (か、f of a to, b to c)でもいい
(a->b)->(a->c)
は、a arrow b, arrow (or to), a arrow c
,は少しの間 2つの型クラスの間に包含関係を付けるのに
MonadからApplicativeのときみたいに
一方を定義すれば自動的に他方が導出されるようにするのと、
FunctorからApplicativeのときみたいに
一方を定義してからでないと他方を定義できないようにするのと、
どっちのやり方がいいのかな 変数に再代入できる言語に
慣れきっている者の質問なのですが
[1,2,3,4,6,7,8]を順次加算して
[0,1,3,6,10,16,23,31]にする関数を
Githubの作例を参考に実装してみたのですが
直感的に解りづらく、
foldを使ってもっと簡潔・簡単にできないものでしょうか。
ints1 :: [Int]
ints1 = [1,2,3,4,6,7,8]
fn :: Int -> [Int] -> [Int] -> [Int]
fn n [] acum = n : acum
fn n (i : ints) acum = fn (n + i) ints (n : acum)
-- reverse $ fn 0 ints1 [] scanl (+) 0 [1..8] では?
素人なのでわからないけど 842です
foldで書いてみました
fn :: [int] → [int]
fn = foldl (\acc x → acc ++ [last acc+x]) [0]
-- fn [1..8] >>841 >>842
どうもありがとうございます。
驚くほど簡潔に書けるものですね!
今まで気にしなかった (++) の有用性を理解しました。
ありがとうございます。 >>843
どうもありがとうございます。
驚くほど簡潔に書けるものですね!
今まで気にしなかった (++) の有用性を理解しました。
ありがとうございます。 842です
いえいえ、私も初学者なので
scanl はともかく、foldl の方はどうかなと
先輩諸兄のレスを待ってください 何使ってもいいならData.Listのinitsを使って
map sum $ inits [1..8]
が楽チン。 >>840
継承クラスに相当するのがMonad=>Applicativeタイプ
委譲クラスに相当するのがFunctor=>Applicativeタイプ
>>841
The Haskell 98 Report
8 Standard Prelude
https://www.haskell.org/onlinereport/standard-prelude.html
scanl :: (a -> b -> a) -> a -> [b] -> [a]
scanl f q xs = q : (case xs of
[] -> []
x:xs -> scanl f (f q x) xs)
scanr :: (a -> b -> b) -> b -> [a] -> [b]
scanr f q0 [] = [q0]
scanr f q0 (x:xs) = f x q : qs
where qs@(q:_) = scanr f q0 xs 正直全然読みやすくないのだが、本当に読みやすくないのか俺が手続き脳なだけなのか判断がつかない >>849
qのところが(f q x)に替わって再帰してるだけだよ
scanl (+) 0 [1,2,3,4]
= 0 : scanl (+) (0 + 1) [2,3,4]
= 0 : 1 : scaln (+) (1 + 2) [3,4]
= 0 : 1 : 3 : scanl (+) (3 + 3) [4]
= 0 : 1 : 3 : 6 : scanl (+) (6 + 4) []
= 0 : 1 : 3 : 6 : 10 : []
= [0,1,3,6,10] if then elseを最近知った位の超初心者です。
(自分の頭以外に)どこが悪いのかわからないので教えていただきたくて投稿します。
kld1 p q = do -- Kullback-Leibler divergence
-- if length p /= length q
-- then return ()
-- else do
let pp = map (/sum(p)) p
qq = map (/sum(q)) q
in sum $ zipWith (\x y -> x * (log x)/(log y)) pp qq
*Main> kld1 [1/2,1/2] [1/4,3/4]
1.4547104198266045
と動作しますが、エラー処理のコメントアウトを外すとコンパイルはできても
kld2 p q = do -- Kullback-Leibler divergence
if length p /= length q
then return ()
else do
let pp = map (/sum(p)) p
qq = map (/sum(q)) q
in sum $ zipWith (\x y -> x * (log x)/(log y)) pp qq
*Main> kld2 [1/2,1/2] [1/4,3/4]
<interactive>:16:1: error:
? No instance for (Floating (m0 ())) arising from a use of ‘it’
? In a stmt of an interactive GHCi command: print it
と返ってきてエラーメッセージの意味すら理解できません。
if ~ elseの部分はどう直せばいいのでしょうか?
モナドも未学習の超初心者ですので、宜しくお願いします(_ _)。 >>852
型を合わせるにはどう対処すればいいのかわからないのですが、
とりあえず、これで動きました。
kld p q = do -- Kullback-Leibler divergence
if length p /= length q
then error "Not equal length"
else do
let pp = map (/sum(p)) p
qq = map (/sum(q)) q
in sum $ zipWith (\x y -> x * (log x)/(log y)) pp qq
main = do
print $ kld [1,1] [1,3]
print $ kld [1,1] [1,2,3] ■ このスレッドは過去ログ倉庫に格納されています