関数型プログラミング言語Haskell Part30 [無断転載禁止]©2ch.net

■ このスレッドは過去ログ倉庫に格納されています
2017/01/15(日) 23:43:54.28ID:Vh4eztBk
関数型プログラミング言語 Haskell について語るスレです。

haskell.org (公式サイト)
http://www.haskell.org/

前スレ
関数型プログラミング言語Haskell Part28
http://echo.2ch.net/test/read.cgi/tech/1428597032/
2017/05/26(金) 19:40:17.16ID:xBragGUI
>>556
セクションは部分適用した二項演算子のことだぞ
2017/05/26(金) 20:51:35.80ID:ovKX6RUR
あれ、どっちもセクションじゃ無かったっけ?と久しぶりに調べたら。。。
前置き形式?で良いのかな?
これは済まんかった。
2017/05/26(金) 21:07:05.78ID:lBtW1IaY
>>553
>良くも悪くも変人しかHaskellなんて覚えようと思わないからじゃないかな
>明らかに文法が異質だもの

ML系のワリと平凡な文法なんだけどね
2017/05/26(金) 21:28:16.56ID:TC/C61F7
変な文法と言えばPrologとかJ言語とか
2017/05/26(金) 21:36:15.75ID:ovKX6RUR
>>558
OCamlもHaskellも同じML系なのにどうしてそう感じたんだろう?
おいらみたいな使ってるやつの印象ってだけだったり?
おいらみたいなのは少数派だよ。
声が大きいから、たくさん居るように感じるだけ。
2017/05/26(金) 21:41:20.55ID:0YCuYapQ
すみません、質問です
f :: a -> b と g :: a -> c があったときに
\x -> (f x, g x) に相当する関数はライブラリに用意されてますか?
2017/05/26(金) 22:01:30.73ID:ovKX6RUR
>>564
Jは聞いた事はあっても触った事すらないので何とも言えないが、Prologは昔の関数型言語の本では次世代言語として紹介されてたな。
実際触って見て可能性自体は感じるんだが、引数が大文字始まりじゃないとダメとか、計算式が=じゃなくてisとかが、とにかく愛せなかった。。。

Prolog得意の家系図関数も、Prologなら自動で関係を見つけるのをHaskellだと家系図をモデルとした仕様書いて、関係性のルール見抜いて仕様にして、そのまま家系図をデータ型に、関係性のルールを関数にする。

関数はルールの条件を箇条書きすればそのままパターンマッチの関数になる。
この辺が手続き型言語に対するアドバンテージであり、Prologに対して見劣りする所。

でも関係性のルールを見抜く作業と、関数作る作業が私にとっては楽しいのでそれで良い。
2017/05/26(金) 22:03:34.66ID:EgTlEiWL
>>566
Control.Arrow の (&&&) だ。
2017/05/26(金) 22:07:24.39ID:ovKX6RUR
>>566
型でHoogle検索して見ては?
探すより作った方が早そうだが。

dfunc f g x = (f x, g x)
2017/05/26(金) 22:16:23.90ID:0YCuYapQ
>>569
(a -> b) -> (a -> c) -> a -> (b, c) とかで検索しても出なかったんですが
検索の仕方が悪かったのかな

>>568
そんな関数があったんですね、勉強になりました
ありがとうございます
2017/05/26(金) 22:34:36.00ID:ovKX6RUR
>>568
演算子としての使い方分からなくてググったわw
ほへー。。。
Arrowって基本こう使うのね。
こりゃHaskell分かりにくいってなる訳だよ。
2017/05/26(金) 23:18:50.05ID:npmNm3qp
型シグネチャから利用法読み解くのはIQモンスターでないと無理
設計者の思想を語ってもらわないと
2017/05/26(金) 23:54:53.85ID:nlWdhydN
結局>>566は解決したんかな。。。
用途に合わせて自作した方が早いし読みやすいと思うんだが。

格好いいからって過剰にArrow使ったりってのもなぁ。
もうそっちのが慣れてて早いんなら別だが。
2017/05/27(土) 00:13:32.94ID:ChWjXNtT
データフローを記述するようなコードならArrow使えばいい
2017/05/27(土) 00:28:51.27ID:Cj0QDtYS
そうね。
逆にxと関数のリスト二つ受け取って、(f x, g x)のリストを得るとかだと引数の順番好きに選べる普通の関数のが良いと思う。

dfunc x f g = (f x, g f)

なりそう言うラムダ式をmapのリスト二つ版(仮にmap2)を作って渡せば良い。

結局>>566が何をしたかったかによる。
2017/05/27(土) 01:16:44.64ID:BlrnYoHB
Control.ApplicativeのliftA2を使って
liftA2 (,) f g
でもいけるよ。
2017/05/27(土) 07:13:42.02ID:BlrnYoHB
昨日の事件について、意見を書いた
http://anond.hatelabo.jp/20140515010237
578デフォルトの名無しさん
垢版 |
2017/05/27(土) 08:54:38.45ID:pQ5DUsdI
>>539
頭悪い会話すぎて笑った
2017/05/27(土) 08:59:16.85ID:ChWjXNtT
>>576
>liftA2 (,) f g

あー、関数アプリカティブか。
2017/05/27(土) 10:15:02.70ID:y8N3m0Nz
>>572
型だろうが思想だろうが同じこと
コードを1行も書かなくても分かり合えるのはIQモンスターだけ
2017/05/27(土) 10:32:14.53ID:C4ObyqB4
おまいらが楽する分Haskellコンパイラの
作成が激ムズになる件。
2017/05/27(土) 10:59:01.67ID:y8N3m0Nz
>>573
格好いいからじゃなくて
Monadはカリー化を過剰に使ってるからタプルを使わない
だからタプルに関係のあるものはArrowの方に集まってくる
2017/05/27(土) 12:15:10.10ID:yeXCnzln
>>582
そういう理由で使われてたのか
理論的にArrowベースのことやってるのかと思ってた
2017/05/27(土) 12:23:21.54ID:Vkpp8Cst
>>533
succの逆はpredな
デクリメントではない
2017/05/27(土) 13:39:14.00ID:zKKPdOe3
****sucking の逆教えてや
2017/05/27(土) 16:44:16.35ID:ectnCudZ
>>585
****vomit
2017/05/28(日) 01:36:41.46ID:i0C/srSl
ちょっ違うなVomit****だ
2017/05/28(日) 09:27:04.54ID:s8SCebgh
-rw------- 1 root root 13796 5月 25 23:39 /usr/share/man/man1/cabal.1.gz
ArchLinuxでcabalのmanが読めないのはなんかのいぢめですか?
2017/05/28(日) 13:11:13.15ID:wvAEkP6f
リストのn番目の要素をaからbに変えたリストを返す関数とかないですかね?
splitAtで分けてから加工してまた繋げればいいのかな
2017/05/28(日) 13:22:58.81ID:Ga0OokE+
>>589
ilist というライブラリに Data.List.Index.setAt :: Int -> a -> [a] -> [a] という
質問そのものの関数があるよ。
2017/05/28(日) 20:35:00.08ID:Rx3nBVE8
一目、効率悪そう
2017/05/28(日) 22:10:57.08ID:3aZpEfHH
元のリストを破壊することなく新しいリストを作るからね
不特定多数から参照されるデータは破壊できないから効率が悪い

所有権がないと参照できないような仕組みがあれば良いのか
2017/05/28(日) 22:31:00.36ID:A2iCvXLz
>>589
nとaと(x:xs)受け取ってnが0になったらxの代わりにaをcons(:)すればいい。

setAt _ _ [] = []
setAt 0 a (_:xs) = a:xs
setAt n a (x;cs) = x:setAt (n - 1) a xs
2017/05/28(日) 23:05:39.10ID:Ga0OokE+
>>593
それ、質問者の言う splitAt で分けてからっていう方法と同じ
2017/05/28(日) 23:14:43.47ID:wvAEkP6f
>>590
>>593

ありがとうございます
Data.IndexのsetAt関数の定義をそのまま使わせてもらおうと思います
2017/05/28(日) 23:23:12.14ID:Rx3nBVE8
リストのコピーって、(既にある)リストの各要素の格納先と同じアドレスを指すポインタを新規アロケートしてく感じですか?

それとも一々要素までをもコピーするんですか?
2017/05/29(月) 00:33:15.43ID:21264BYs
コピーしてたらリストの意味無いからアドレスを新しく指してるんだと思う。
でないと、ソートとかメモリ幾らあっても足りなくなる。
2017/05/29(月) 00:49:02.28ID:21264BYs
>>594
SplitAtで分けると前方がリストになる。
(++)と(:)じゃ(:)のが効率が良い。
(++)は前方のリストが長くなると著しく遅くなる性質がある。
2017/05/29(月) 01:12:03.29ID:21264BYs
>>594
ちなみにsplitAtのやり方だとtake n zsの一番最後が更新したい場所になるので、initした上で++[a]++ysする必要がある。

setAt n a zs = init xs ++ [a] ++ ys
.........................where (xs, ys) = splitAt zs

Haskellでswap関数を作る7つの方法とか言うページ思い出したわ。。。
2017/05/29(月) 01:13:40.94ID:21264BYs
x splitAt zs
o splitAt n zs
2017/05/29(月) 06:42:46.07ID:0mYha2aU
(++) (x:xs) ys = x : (++) xs ys
setAt n a (x:xs) = x : setAt (n-1) a xs

これを比較して前者が著しく遅いというのは嘘八百だな
2017/05/29(月) 06:59:53.71ID:Ny51uA9N
>>601
reverse関数をfoldl (\x -> x:ls) [] xsで書くのとreverse xs ++ [x]で作るのじゃ反転した文字列が生成される度に右から結合されて凄く遅い。

上の>>599も、init xs ++ [a]で一旦結合して、++ ysの部分に来たらまたinit xs部分から結合が始まる。
2017/05/29(月) 07:04:59.77ID:Ny51uA9N
あ、逆か。
ysから始まってリストの先頭まで結合する。

出力する際には結局先頭から(:)伝いに辿って行くのでそう言う二度手間は避けた方がいい。
2017/05/29(月) 07:20:56.98ID:Ny51uA9N
ここで言う問題は、++ysそのものに害は無いけど、init xs ++ [a]で一旦先頭まで結合する処理が挟まってるってことね。
2017/05/29(月) 07:35:03.41ID:0mYha2aU
実は++も右結合なんだよな
だから init xs ++ [a] ++ ys を (init xs ++ [a]) ++ ys と解釈するのは絶対ダメ
606デフォルトの名無しさん
垢版 |
2017/05/29(月) 07:35:56.11ID:Dokhp7Id
setAt i x xs = let (ys,_:zs) = splitAt (i-1) xs in ys ++ x : xs
別にこういう定義にすればいい
でこれが遅いのは単にysの部分が2パスになるから
607デフォルトの名無しさん
垢版 |
2017/05/29(月) 07:39:00.53ID:Dokhp7Id
>>606
ミス
x : xsじゃなくてx : zs
2017/05/29(月) 07:52:38.57ID:KKAtyjp+
別にそれでも良い。
(++)は取り扱い次第で遅くなるってだけ。
2017/05/29(月) 15:03:33.95ID:2+2L65e+
というわけで、Sequenceです
2017/05/29(月) 20:13:36.52ID:0mYha2aU
showで文字列を作るのは平気なのにリストを作ると遅い遅いと言われる現象
数学的というより人間工学っぽい
2017/05/29(月) 20:46:32.77ID:VknhjnwZ
出現頻度の問題では?
2017/05/29(月) 21:27:07.82ID:0mYha2aU
リストを使う頻度はIOを使う頻度と関係ありそう
IOを使う頻度は個人差が非常に大きい
2017/05/29(月) 21:54:24.18ID:2+2L65e+
初心者はモナド変換で躓く
2017/05/30(火) 04:05:18.67ID:jc1LxPHe
例外処理のベストプラクティスがよく分からないなー
catchとかhandleでメイン処理、例外処理共に複数行になる時に、命令型のtry~catchみたいに無名関数での書き方ってどうなるんだろう
関数に切り出して呼ぶべし、なんかな?
どっちかだけ複数行ならそっちをdoにしたら良いっていうのは分るんだけど
2017/05/30(火) 05:14:25.23ID:jc1LxPHe
パーレンで囲んだラムダは複数行いけるのな、見た目微妙だけど
616デフォルトの名無しさん
垢版 |
2017/05/31(水) 03:43:11.48ID:ML3xxqnu
パーレン ()
ブラケット []
ブレース {}
2017/06/03(土) 16:54:41.37ID:c6fwatRb
f g n = gをn回合成した関数
みたいな関数のが欲しい
2017/06/03(土) 17:14:18.00ID:PKJ3i7am
f = (!! n) . (iterate g)
2017/06/03(土) 18:46:29.60ID:RovdiJA/
>>618
それって真面目なコードで使っていいのか?
融合変換で実質ループなのは知ってるけど
そもそもこのレベルを勝手に抽象化していいものかどうか
2017/06/03(土) 20:14:20.72ID:lhcAcbkl
なんの問題もないと思うけど

そもそも同じ関数の反復適用が iterate なんだから
たいして抽象的でもない
2017/06/03(土) 20:24:38.74ID:lhcAcbkl
iterative f n = foldl1 (.) $ take n $ repeat f


これより >>618 の方がわかりやすいと思う
2017/06/03(土) 20:28:35.64ID:lhcAcbkl
iterative f n = foldl' (.) id . map (const f) $ [1..n]

とかでもいいか。そして iterate の方があきらかにわかりやすい。
2017/06/04(日) 00:13:00.20ID:zJIyEnOK
Cabalプロジェクトをstackでビルドできないだろうか?
cabalをグローバルにインストールしたくないんだ
624デフォルトの名無しさん
垢版 |
2017/06/07(水) 04:45:18.83ID:WOFnqCYP
haskellで○×ゲーム作りました(頑張った私を褒めてください)
https://ideone.com/HHEWZv
2017/06/07(水) 08:42:17.54ID:gpLNw8mo
勝利判定なんとかならんのかw
2017/06/07(水) 10:28:15.63ID:ZiMqMUeJ
ゲームとかアルゴリズムとかどうでもよくて、ここが可愛いってのがポイントだろ?

('o':'o':'o': _ : _ : _ : _ : _ : _ :_) -> True
( _ : _ :'x': _ :'x': _ :'x': _ : _ :_) -> True
2017/06/07(水) 17:37:30.82ID:goEom//K
下は泣いてるミッフィーちゃんがクローン技術で失敗したような感じ
2017/06/07(水) 22:12:38.86ID:FEgyIbtW
昔オセロ作ったけど、勝敗判定作るの忘れて延々パスし続けたわ

main =
    void $ loop (player >=> ai) initBoard
        where loop :: (Board -> IO Board) -> Board -> IO Board
              loop f ib = loop f =<< f ib
2017/06/08(木) 02:06:09.79ID:3NnY77Pk
>>624
同じゲームでも人によって設計や実装が全然違ってて面白いな

○×ゲーム - a-sanの日記 - haskell
https://haskell.g.hatena.ne.jp/a-san/20070115/p1

yasuabe blog: Haskell で三目並べ (2)
http://yasutech.blogspot.jp/2012/03/haskell.html

examples/TicTacToe.hs
http://projects.haskell.org/operational/examples/TicTacToe.hs.html

TicTacToe - HaskellWiki
https://wiki.haskell.org/TicTacToe

Tic-tac-toe in Haskell ・ GitHub
https://gist.github.com/billdozr/3071732
2017/06/11(日) 01:46:27.90ID:vYdG9fRO
開発環境としてleksahを入れてみたんですが、getLineのような標準入力が上手く動いてない気がします
実行しても入力出来るようにならず止まってしまうのですが、どうしたら入力出来るようになりますか?
2017/06/11(日) 05:15:07.62ID:afWo9qoQ
今気づいた! leksah ってHaskell逆読みじゃん!
2017/06/11(日) 12:39:02.23ID:hZZQfw5d
月並な命名をされた月並なアプリ
2017/06/11(日) 16:52:05.15ID:3HVnXb8h
>>68
> ["aa", "bb", f ["cc", "dd"] ] =
> ["aa", "bb", "cc", "dd"]
> となるような関数fはどのように書けるでしょうか

めちゃ遅レスでなんだけど、f [x, y] = x : [y] ではだめなの?
2017/06/11(日) 17:45:34.43ID:uxrAPwUF
>>633
自分でちゃんとテストしてみた?
2017/06/11(日) 22:56:26.81ID:3HVnXb8h
>>634
リストの定義から明らかだと思うのでテストはしていない
636デフォルトの名無しさん
垢版 |
2017/06/11(日) 23:16:23.58ID:0ffmynih
>>635
リストの定義から明らかだが、>>69
2017/06/11(日) 23:46:34.97ID:QTMXbNo3
驚き最小=テスト最小の法則
2017/06/11(日) 23:54:46.06ID:3HVnXb8h
>>636
何と何の型がどう合わない?
639デフォルトの名無しさん
垢版 |
2017/06/12(月) 00:18:12.16ID:9+UoMkQw
テンプレート?
2017/06/12(月) 01:00:35.16ID:p/7lEol5
fを適用した結果の型が外側のリストの型と合わないってことでら
2017/06/12(月) 01:38:16.98ID:0O7XnA5J
たぶんshowの結果を評価する途中でunsafePerformIOすればいいんだな
2017/06/12(月) 01:46:50.84ID:4tiz7p+p
[ “aa”, “bb”, [“cc”,”dd”] ]

の型がどうやって合うと思ったのだろうか。
2017/06/12(月) 02:20:04.97ID:DHBWzfrJ
邪悪なことはするな
644デフォルトの名無しさん
垢版 |
2017/06/12(月) 02:47:23.94ID:q+c9m0UT
>>638
文字列型の中に文字列のリスト受け取って文字列を返す関数型が混じってる。
2017/06/12(月) 09:44:54.21ID:4tNZZp5I
>>644

それは違う。関数型が混じってるんじゃない。

>>642

["a", "b", ["c", "d"]]
= "a" : ("b" : ["c", "d"])
= "a" : ("b" : ("c" : "d"))
= ["a", "b", "c", "d"]

じゃないの?
2017/06/12(月) 09:53:23.55ID:4tNZZp5I
>>642
自己解決しますたw nilをきちんと入れてなかったみたい。
647デフォルトの名無しさん
垢版 |
2017/06/12(月) 17:07:14.08ID:uTHinYqc
>>645
関数自体も値なのだが。。。
仮に返り値だとしても、文字列のリストにさらに文字列のリストが入ってるので型が合わない。

["a","b",["c","d"]]
="a":"b":["c","d"]:[] --["c","d"]が一つの値なので、文字列じゃない!!とエラーになる。
2017/06/12(月) 17:22:26.96ID:pxvA8Fxv
なんでここでnilの話になるんですか?
2017/06/12(月) 18:54:07.23ID:rXVGv3m5
どうしてもできないときは、それはする価値がないのだ

= 何かをしたくて、その手段としてそれをしようとしているが、実は何かはそれでなく別の方法でより自然に実現できることが多い。無理矢理その手段を開発する価値が本当にあるのか、もう一度考えてみよう
2017/06/12(月) 20:01:13.71ID:4tiz7p+p
GHCi で ["aa", "bb", ["cc", "dd"]] を評価してみれば一発だろうに

• Couldn't match expected type ‘Char’ with actual type ‘[Char]’
• In the expression: "cc"
In the expression: ["cc", "dd"]
In the expression: ["aa", "bb", ["cc", "dd"]]
2017/06/12(月) 21:30:08.56ID:4tNZZp5I
>>647
> ["a","b",["c","d"]]
> = "a":"b":["c","d"]:[] --["c","d"]が一つの値なので、文字列じゃない!!とエラーになる。

文字列または文字列のリストからなるリストというのはあり得るでしょう?
その場合ならエラーではないはず

>>649
> どうしてもできないときは、それはする価値がないのだ

いまの場合、どうしてもできない証明はどうするんだろう?

>>650
> GHCi で ["aa", "bb", ["cc", "dd"]] を評価してみれば一発だろうに

それだけではその評価が本当に正しいかどうかが分からない
2017/06/12(月) 22:36:06.43ID:ejDn/VSN
>>651
> 文字列または文字列のリストからなるリストというのはあり得るでしょう?

文字列というのが String 型を指していて、文字列のリストというのが [String] 型を指しているのであれば、
文字列または文字列のリストからなるリストという型は「あり得ません」。

なぜなら、Haskell には「型A または 型B」という型は存在しないからです。
(data T = D String | E [String] の型は T であって、D や E ではない)


> いまの場合、どうしてもできない証明はどうするんだろう?

なぜ「証明」を求めるのでしょうか。
Haskell だとこれはできないよと言われ、簡単な理由を説明された時、
あなたはいつもその証明を求めるのですか。
今回の問題に限って求めているのであれば、その理由を説明してください。
理由によっては、あなたが納得できる証明以外の説明ができるかもしれません。
というのも、できないことの証明を本当にしようとすると、かなり難しいからです。
きっと構文規則や意味論にまで話が及びます。
そんな証明できる人は稀ですし、できる能力があっても、したくないでしょう。


> それだけではその評価が本当に正しいかどうかが分からない

あなたの場合、「正しい」とは何を意味するのでしょうか。

>>650 が言っているのはきっと、GHCi で試してみれば「構文エラーであることが分かる」、
ということだと思いますよ。
それが正しいのか分からないというのは、GHC は信用できないということですか。
2017/06/12(月) 22:39:18.30ID:4tiz7p+p
>>651

https://paiza.io/projects/TpKm5_4fBEc7_YoKQIeKJQ

こういうのがお望み?
いずれにせよ List のデータコンストラクタ(:)を持ち出した >>633 は救済できんが。
2017/06/12(月) 22:48:23.36ID:cqbaGfvU
もしかして本当に欲しかったもの:
[["aa"], ["bb"], ["cc", "dd"]]
2017/06/12(月) 22:49:39.74ID:4tiz7p+p
https://paiza.io/projects/4geVOsfwAnMedzLfkbEDpw

こっちのほうがパラメータ多相でいいか。
2017/06/12(月) 22:58:41.14ID:4tiz7p+p
ちなみに、自分自身を要素の型とするかのような「ネストしたリスト」のようなデータ構造(というかinfnite typeのまがいもの)自体はときどき使いたくなるので簡単なライブラリを書いたことはある。そういやOCamlは オプショナルだが infnite type 扱えるんだったっけ??
2017/06/12(月) 23:23:51.05ID:4tNZZp5I
>>652
> なぜなら、Haskell には「型A または 型B」という型は存在しないからです。

「今のHaskell」には存在しないということね?
こっちは今のではなく本来のに興味があるので。

> Haskell だとこれはできないよと言われ、簡単な理由を説明された時、
> あなたはいつもその証明を求めるのですか。

簡単な理由でよいのだが、「今そうなってるから」は興味がない

> あなたの場合、「正しい」とは何を意味するのでしょうか。
> >>650 が言っているのはきっと、GHCi で試してみれば「構文エラーであることが分かる」、
> ということだと思いますよ。

さっきも言ったが、「今そうなってる」というのは 「正しい」とは異なる
2017/06/12(月) 23:32:25.99
方法が存在しないことの証明って悪魔の証明でないの?
できると主張する側ができることを証明しないとダメだよ

痴漢の言いがかりをつけられて、『痴漢していないことを証明しない限り有罪な』って裁判官に言われて納得できる?
2017/06/12(月) 23:39:48.75ID:4tiz7p+p
>>657はできるという根拠をコードで示せばいい。

Haskell 2010 に従ったコードで、しかしGHCが不当にも
型検査で排除するというような、そういうコードを示せば
話はたちまちに解決する
2017/06/12(月) 23:42:32.96ID:4tiz7p+p
[“aa”, [“bb”,”cc”]]

について Haskell2010 の構文規則をを充足するような
Haskellの型をつけてくれればいい
2017/06/12(月) 23:43:46.21ID:ejDn/VSN
>>657
みんな、特に断りがなければ今のHaskellについて質問したり語ったりしています。

なので、そうでなければ、初めにちゃんと断っておかないと、話が合わなくなります。

また、本来のHaskellとは何かも説明しておかないと、これまた話が合いません。

私は今のところ、今のHaskellでアプリを作ることに興味が向いているので、
そうではない議論からは抜けさせてもらいます。


>>658
方法の存在を仮定した場合に矛盾がおきることを示すことで、方法の非存在を示すやり方もあります。
数学(厳密な論理)の舞台に上げられるテーマであれば友好的な手です。
(面倒かどうかは別にして)
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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