20/09/13 23:57:07.12 Tso/1gLY.net
へ?何言ってんの
もしかすると、何言ってんのが前の投稿にかかっちゃったかもしれない。
何も考えずに、何言ってんのおじさんプレイを楽しんでいるだけなので、
気にしないでほしい。
ついでなので。
`return x = x / x`という選択は、集合の圏では、取りうる唯一の選択肢かも
しれない。自分も他に思いつかない。しかし、可換モノイドの圏では、
他にも選択肢がある。それも含めて、
[記事](URLリンク(ncatlab.org))
に全て書いてある。他人事なので断言してしまうが、この記事より詳しい
分数モナドの解説は地球上には存在しない。しかし、悲しいかな、
Haskellの解説記事と同じで、
* わかる人にはわかるが、
* わからん人にはなるほどわからん
といういつものパターンになっていると思う。解説案件の宿命かもね。
522:デフォルトの名無しさん
20/09/14 02:32:09.85 TxRaIMAU.net
>>=は何ですか?
523:デフォルトの名無しさん
20/09/14 02:44:47.64 SnB9iMGf.net
圏論わからんからなんもわからん
524:デフォルトの名無しさん
20/09/14 16:41:03.56 TxRaIMAU.net
Monad という概念が数学の圏論の Monad から来るのはよく解説が見つかるんですが、Applicative (≒Monoidal) については数学からの意味付けが見つかりません
コレ数学的にはなんなんですか?
525:デフォルトの名無しさん
20/09/14 23:29:35.74 XfiH3m4/.net
そのままじゃん アプリカティブファンクター
なんだから、そのまま日本語訳でよくね
つまり、関手 プログラマーにとって使いやすくしただけ
ところで、”Applicative (≒Monoidal)”なのか?
こっちの方がい意味不明なんだが
モノイドって意味なら、≒モナド の方
モナイド則=モノイド則 モナドの方は、自己関手って条件が付くだけ
しらんけど
526:デフォルトの名無しさん
20/09/15 00:17:11.21 wUKRYY2O.net
>>519
まだ自分でハッキリ確かめたわけじゃないんですけど
Applicative と Monoidal は同型なんだそうです
URLリンク(qiita.com)
まだこっちはどういう意味で“同型”になるのかわかってませんけど
数学的な意味でのMonadは英語のwikiに詳しく説明が載ってて↓
URLリンク(en.m.wikipedia.org)(category_theory)
このFormal DefinitionがまさにHaskellのモナド則に繋がっていくのは確かめました
問題はApplicativeは圏論のどの概念に該当するのかの説明がサッパリ見つからないんです
527:デフォルトの名無しさん
20/09/15 02:19:25.61 PObv6BQ8.net
(a -> b) -> (m a -> m b)
m (a -> b) -> (m a -> m b)
(a -> m b) -> (m a -> m b)
こいつらは中央の->と左右の->を区別してないから数学的な意味が見えない
returnとjoinは->が一つしかないから問題ないが
528:デフォルトの名無しさん
20/09/15 10:15:51.98 TeSbfrM9.net
>>521
そう、Haskellの圏論がらみの話はその“冪対象”(exponential object)が絡むのがややこしい
しかしFunctorは当然としてMonadも冪対象を用いないで形式化されてる(というより計算論の世界への応用のずっと以前からある)
Applicative(=Monoid?)はどやねんという話なんです
圏論の世界ではなかったものが計算論の世界に導入されてから考え出されたもんなんですかねぇ?
529:デフォルトの名無しさん
20/09/16 01:31:29.62 yuR5T5xB.net
strong lax monoical functor
530:デフォルトの名無しさん
20/09/16 22:12:52.40 CfmtxJKj.net
モノイド圏とかモノイド対象とかあんのだけど、モノイド(モノイダル)関手ってのもあんのね
読む気は無いんだけど、アプリカティブ関手とモノイダルXXが同型ってのは無いと思うが
っておもったけど、関手同士なんだから、いくつか条件つければモナドとモノイドみたいな関係もありうるんかな?
あとは、カン拡張、随伴、普遍性(極限だっけ?) どれかから相互に変換出来るだっけ?みたいなもん?
どちらにしろ、定義の話で面白みは無いとは思うのだが
531:デフォルトの名無しさん
20/09/17 10:32:26.07 2a8IoKJu.net
見つけた
URLリンク(qiita.com)
このサイトの人がまとめたpdfに書いてある
とは言ってもやはりclosed categoryは仮定してる
やっぱりapplicativeはmonadと違って“内部ホム”を持たない圏では定義できないんだろな
“内部ホム”もつ圏でmonoidal functorに<*>を定義するのはわりと簡単だけど↓
F(X) × F(Y^X)
→F(X×Y^X) (coherence)
→F(Y) (F(eval))
URLリンク(en.m.wikipedia.org)
pureが全然できんなぁと思ってたら“strong”という条件からpureが作れるんだな
まぁHaskellて圏の話するときはHASKて言えればいいんだからコレでわかったことにしよ
532:デフォルトの名無しさん
20/09/28 01:41:48.03 0EuZ+v5t.net
[Promise](URLリンク(developer.mozilla.org))
の小さい例題の[html](URLリンク(pastebin.com))をアップした。
async/awaitはPromiseのお助け文法になっているが、それは扱っていない。実行環境は、
[RStudio](URLリンク(rstudio.com))から
[Node.js](URLリンク(nodejs.org))を呼び出している。
533:デフォルトの名無しさん
20/10/12 16:08:54.17 Wx/lfAmjI
挑戦する馬鹿として生きるか?批判だけする雑魚として死ぬか?
URLリンク(www.youtube.com)
奴隷職に就く★自ら奴隷を選んで不満を言う愚かさ
URLリンク(www.youtube.com)
バカは騙され最低賃金でコキ使われる★物価とか関係なし
URLリンク(www.youtube.com)
勉強しないから奴隷人生★実業と人を残す人生哲学
URLリンク(www.youtube.com)
正社員特権が「ブラック社員」を生む★正社員は訴え放題
URLリンク(www.youtube.com)
「で、年収は?」と聞くバカとは合わない社長業
URLリンク(www.youtube.com)
534:デフォルトの名無しさん
20/10/14 04:31:41.26 +VLXbnA3.net
>>20
ワードカウントのロジックが不思議ちゃんだと思ったけどワードと空白の関係が
"abc dd "みたいな行儀が良い書式じゃないとだめなんだな
" "一文字スペースでワード数が1になってしまうみたいな
countFile :: String -> (Int, Int, Int)
countFile s =
let (cs, ws, ls, _) = foldl' go (0, 0, 0, False) s
in (cs, ws, ls)
where
go :: (Int, Int, Int, Bool) -> Char -> (Int, Int, Int, Bool)
go (cs, ws, ls, wasSpace) c =
let addLine | c == '\n' = 1
| otherwise = 0
addWord | wasSpace = 0
| isSpace c = 1
| otherwise = 0
in (cs + 1, ws + addWord, ls + addLine, isSpace c)
535:デフォルトの名無しさん
20/10/31 09:11:59.11 UJYxitvT.net
URLリンク(walk.northcol.org)
>代数的データ型(algebraic data type)とは,図のように木構造で表現される値からなるデータ型のことです.
必ず木構造に限定されるんだろうか?
OOPではオブジェクトグラフがありネットワークになりうるが、
Haskellでは絶対に木と考えて良いの?
536:デフォルトの名無しさん
20/10/31 12:29:50.75 cEs7BAmA.net
いいんじゃない?
型の全体は文脈自由文法で規定されるクラスだから木になる希ガス
537:デフォルトの名無しさん
20/10/31 12:34:33.57 fxcwqRC2.net
この木なんの木きのこる木
538:デフォルトの名無しさん
20/10/31 12:37:07.03 CAmth+XY.net
見たこともない木ですから
独自実装のバグが出るでしょう
539:デフォルトの名無しさん
20/10/31 13:17:41.17 cEs7BAmA.net
でもよくよく考えたらHaskellのデータ型って「展開できる表現がひとつもないデータ型」もありうるんだな
無限の木になる
data InfiniteSequence = IS {car :: Int, cdr :: InfiniteSequence}
arithSeq a d = IS a $ arithSeq (a+d) d
term 0 (IS x y) = x
term n (IS x y) = term (n-1) y
main = print $ term 10 $ arithSeq 5 3
----
53
540:デフォルトの名無しさん
20/10/31 13:26:01.44 UJYxitvT.net
再帰的なデータ型はグラフにできるのでは?
541:デフォルトの名無しさん
20/10/31 13:37:30.03 B0ELcd4k.net
最終的に暴走しないで展開が停止するものだけをデータ型と呼ぶならそうだけど、iterate (+4) 5 ですら無限の木になってしまう
542:デフォルトの名無しさん
20/10/31 21:13:27.13 3k5Im+3l.net
haskellの配列は代数的データ型でばないのか?
543:デフォルトの名無しさん
20/10/31 22:07:18.29 XiPKdEPZ.net
foldrなどの引数のことを代数的と言っていたような気がする
引数は(:)と[]でもいいし
(+)と0でもいい
引数を渡すと関数 [a] -> b が返ってくるが
これは関数というよりOOPの継承関係のような印象
544:デフォルトの名無しさん
20/10/31 22:34:53.43 B0ELcd4k.net
Haskell のデータ型は再帰を許すからな
どうしても「終端記号(大文字から始まるData constructet) を木構造に並べたもの」という説明をしたいなら無限グラフを使わざるをえない
545:デフォルトの名無しさん
20/11/01 07:14:51.56 fIYIMdhR.net
URLリンク(walk.northcol.org)
1)foldr (+) 0 [1, 2, 3]
(+)とカッコがつく理由は?
2)map' f = foldr (\x a -> f x : a) []
xは[]の各要素?aは何?
546:デフォルトの名無しさん
20/11/01 08:58:44.92 Srz4hpJo.net
1)
URLリンク(walk.northcol.org)
2)
このままだと対応する値が存在しないので、少し書き換える
map' f xs = foldr (\x a -> f x : a) [] xs
xはxsの各要素、aは最後の要素では[]で、
それ以前は後ろの要素に(\x a -> f x : a)を適用した結果
547:デフォルトの名無しさん
20/11/01 09:15:58.91 v6ASK7zT.net
>>539
>
> 1)foldr (+) 0 [1, 2, 3]
> (+)とカッコがつく理由は?
+ がないと+は中置演算子で
(foldr + 0) [1, 2, 3]
になる
(+)があると普通の関数としてfoldrの因数として解釈される
> 2)map' f = foldr (\x a -> f x : a) []
> xは[]の各要素?aは何?
[]はfoldrの第3因数と同じ型の空集合
a は無名函数(\x a -> f x : a)の第2因数
定義に従ってmap' sin [] [5,6]] はわかりやすく(\x a -> sin x : a)を中置演算子++++で書くと(すなわちx ++++ a = (sin x) : aとすると)
map' sin [] [5,6]
= 5 ++++ ( 6 ++++ [] )
= 5 ++++ ( (sin 6) : [] )
= 5 ++++ [ (sin 6) ]
= [ (sin 5) : [ (sin 6) ]
= [ (sin 5) , (sin 6) ]
となる
548:デフォルトの名無しさん
20/11/01 10:14:49.54 1eMkmBeN.net
因数?引数ではなく?
Haskell用語なのかな
549:デフォルトの名無しさん
20/11/01 10:21:30.53 Srz4hpJo.net
1)
foldr + 0 [1,2,3]
と書いた場合、「+」より関数適用のほうが優先順位が高いので、
foldr + (0 [1,2,3])
と解釈される。
つまり、0という関数を[1,2,3]という引数に適用したものと、foldrを足し算するという意味となる
2)
具体例
map' f [1,2,3] = foldr (\x a -> f x : a) [1,2,3]
3番目の値
(\x a -> f x : a) 3 [] = f 3 : [] = [f 3]
2番目の値
(\x a -> f x : a) 2 [f 3] = f 2 : [f 3] = [f 2, f 3]
1番目の値
(\x a -> f x : a) 1 [f 2, f 3] = f 1 : [f 2, f 3] = [f 1, f 2, f 3]
550:デフォルトの名無しさん
20/11/01 10:25:40.23 Srz4hpJo.net
おっと、具体例の「foldr (\x a -> f x : a) [1,2,3]」は
「foldr (\x a -> f x : a) [] [1,2,3]」の誤り
551:デフォルトの名無しさん
20/11/01 10:36:13.55 B/d//mYI.net
い・・・引数
552:デフォルトの名無しさん
20/11/01 10:54:46.55 z/eHKN3/.net
引数です
orz
普段“因数”の方が使う人なのでうっかりしたorz
553:デフォルトの名無しさん
20/11/01 11:03:53.67 93fSMn/e.net
こ・・・因数
554:デフォルトの名無しさん
20/11/01 11:05:28.12 z/eHKN3/.net
こ?
555:デフォルトの名無しさん
20/11/01 11:11:25.51 4+fLUvoM.net
だ…因数
556:デフォルトの名無しさん
20/11/01 12:57:34.37 9/8GaKcH.net
ひきすう
557:デフォルトの名無しさん
20/11/01 15:22:11.82 N8AW169o.net
引数を「ひきすう」と読むのは、同音異義語との混同を避けるための慣用読みだと思ってた
化学(ばけがく)、鼻腔(びくう)みたいな
558:デフォルトの名無しさん
20/11/01 15:24:45.41 BdB3gM+x.net
返り血
559:デフォルトの名無しさん
20/11/01 17:34:03.38 S9fsJ+JS.net
Parameterとargumentsの違いがよくわからない
560:デフォルトの名無しさん
20/11/01 17:44:50.76 5aO2zs3I.net
URLリンク(qiita.com)
だってよ
561:デフォルトの名無しさん
20/11/01 17:59:46.68 S9fsJ+JS.net
よくわからんし一緒ってことか
562:デフォルトの名無しさん
20/11/02 00:43:34.64 TnMF05Pn.net
質問です
このサイトでNum instanceをDerivingする話が出てました
URLリンク(qiita.com)
実際このページの次のコードはうちの環境でも通ります
Haskell Online Compiler [ghc-8.4.4]
Copyright (c) The University of Glasgow
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Quantity = Quantity Int
deriving (Eq, Ord, Num, Show)
a = Quantity 2
b = Quantity 6
totalQuantity :: Quantity
totalQuantity = a + b
-- Quantity 8
しかし次は通りません
通す事はできますか?
import Text.ParserCombinators.Parsec
import Text.Parsec (Parsec)
newtype ParserInt = PI (Parser Int) deriving (Num)
563:デフォルトの名無しさん
20/11/02 00:43:43.72 TnMF05Pn.net
---- エラーメッセージ
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:6:47: error:
• No instance for (Num (Parser Int))
arising from the 'deriving' clause of a data type declaration
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
• When deriving the instance for (Num ParserInt)
|
6 | newtype ParserInt = PI (Parser Int) deriving (Num)
| ^^^
564:デフォルトの名無しさん
20/11/02 21:44:04.17 aBc5dqas.net
こうすりゃ無理やり通すことはできるけど、
そもそもパーサ同士の足し算等々でどう動いて欲しいのか分からんから
まともなインスタンス宣言が書けん
{-# LANGUAGE FlexibleInstances #-}
instance Num (Parser Int) where
x + y = x
x * y = x
abs x = x
signum x = x
negate x = x
fromInteger n = return 0
565:デフォルトの名無しさん
20/11/02 23:56:16.57 Zq9JUsOb.net
>>558
元は別スレに出てた問題で
「与えられた文字列の中で“trickと"treat”どっちが先に出てくるか判定せよ」
なんです
とりあえずparserを与える関数として
makeP = mconcat . map ( manyTill anyChar . char )
でできました
コレを例えば"abc"にapplyするとmtl = manyTill、ac=anyCharとして
(mtl ac $ char 'a') <> (mtl ac $ char 'b') <> (mtl ac $ char 'c'>
というparserになりコレにhiajklbcnという文字列をparseするとhijklとabcが出現するするまでに読み飛ばした文字列を返してくれます
それでお題の答えとしてparseの結果を
lastInd x s = case ( runParser ( makeP x ) () "" s ) of
Left _ -> ( [ 2, 0 ] , x )
Right y -> ( [ 0, length $ x ++ y ], x )
のようにしてlengthで数えたんです
しかしちょっと冗長なかんじがします
そもそも読み飛ばした文字列なんか欲しいわけではなく読み飛ばした文字数が欲しいだけだからほんとは
Parser String 型ではなく例えば
length <$> ( manyTill anyChar ( char 'x')
とかのParser Intで十分です
問題はコレをどうやって繋げて総和を返すコンビネータを作ろうかというところなんです
Parser Stringはmonoid型を持ってるのでmconcat一発で繋げられるんですがParser IntはNum持ってないのでsum一発で繋げるというわけにはいかないんです
なんとかできないかと探してみるとなんか「Numをderivingする」という記事を見つけて、お、コレでいけないかと色々やってみたんですがやはりParser Intにderiving一髪でNum入れる方法見つからなくてなんとかならんもんかと
566:デフォルトの名無しさん
20/11/03 01:59:40.73 WdkpFDBO.net
わざわざNumのインスタンスにしなくても、これでいいのでは
makeP = fmap sum . mapM ( fmap length . manyTill anyChar . char )
567:デフォルトの名無しさん
20/11/03 10:26:04.44 qaG2IpUi.net
>>560
うん、まぁ別にNumのインスタンス入れなくてもこの問題の話だけならいくらでも方法はあると思うんだけど、そもそもモナドってもこういう時のためにあるんじゃないのかなと思って
例えば(+)なら Num a,Functor f のとき Num (f a)は自然には導出できない、なぜなら fmap (+) は f a -> f ( a - > a ) になってしまう
しかし Applicative f なら lifaA2 (+) がピッタリ f a -> f a -> f a になって自然にキレイに Num (f a) が導出できる
だからすごく理論的には自然なのに方法がないのは何故なんだろうと
というかderiving (...) の (...) にかけるやつとダメなやつの基準がわからない
実用本位でよく使うやつだけ用意されてるに過ぎないのかな?
568:デフォルトの名無しさん
20/11/03 11:32:34.46 WdkpFDBO.net
一応、Num (f a)は導出できるけど、それで定義した(+)だと
交換則(x + y = y + x)が成り立つ保証がないからじゃないかねぇ
(パーサの順番を入れ替えた場合を考えるとわかりやすい)
{-# LANGUAGE FlexibleInstances #-}
instance (Num a, Applicative f) => Num (f a) where
x + y = (+) <$> x <*> y
x * y = (*) <$> x <*> y
abs x = abs <$> x
signum x = signum <$> x
negate x = negate <$> x
fromInteger n = pure $ fromInteger n
569:デフォルトの名無しさん
20/11/03 11:50:57.17 hn8kPJNe.net
>>562
なるほど、文法的に通っても意味的に文法には出てこない"Num rule"が補償されないからダメって事なのかな?
まぁ今はclassのメンバ関数の自分が利用するやつだけ定義する必要無くなったみたいだから手で書いてもいいんだけど、>>556の例だと
newtype Eval a = Eval (ReaderT Env (ExceptT String Identity) a)
deriving (Functor, Applicative, Monad, MonadReader Env, MonadError String)
とかはmonad translater越しにできるし
newtype Quantity = Quantity Int
deriving (Eq, Ord, Num, Show)
もできるのになんで Parser (Int) はあかんねんと
なんかプラクマつけたらいけんもんかと
Num くらいならいいけど Floating とかだと惨劇になってしまう
570:デフォルトの名無しさん
20/11/03 18:12:46.66 oSP8TPsC.net
この話の面白いところは
Parser Intという型を宣言する言語と
そもそも型を宣言しない言語
どっちが生産性高いかってことだよ
571:!id:ignore
20/11/06 20:16:57.19 uZSEyxFl.net
stackくんさぁ、コンパイラのダウンロードが200MB強あるんだから、低速回線は途中で切断されるとかよくありそうなことじゃん
サスペンド・レジューム機能搭載は必須じゃないのかね
きょうびyoutube-dlでさえ向こうに切断Forbiddenされても今までダウンロードした分は残ってて、再度ダウンロードを開始した際には途中から残りの部分をダウンロードすように始まるってのにさ
仮に205.86 MiB / 205.87 MiBまで来て切断された場合
リトライすると0 MiB / 205.87 MiB からだなんてお互い不幸になると思わないのか?
こっちは成功するまで永遠に繰り返すんだぞ? むしろそっちの方がそちらにとっても迷惑じゃん
それとも低速回線は死ねっていう差別的思想を持っているのかね?
572:デフォルトの名無しさん
20/11/08 11:31:57.94 Bx8aZf2L.net
一方TeXはisoイメージを使った
573:デフォルトの名無しさん
20/11/08 13:05:47.79 .net
パターンガードの変数の束縛は局所的なのですが、全ての場合で共通して使用してほしい束縛はどうやりますか?
574:デフォルトの名無しさん
20/11/09 01:15:49.21 4MQyK7K1.net
>>567
質問の意味がよく分からないのだが、コード例を出せる?
こんな風に書けたらいいのに、みたいな。
575:デフォルトの名無しさん
20/11/09 19:55:38.03 .net
rootsInternal :: Quadratic -> Double -> Roots
rootsInternal q d
= let
two_a = 2.0 * (a q)
realpart = - (b q) / two_a
dside d = (sqrt d) / two_a
dpart = dside d
complexpart = dside (-d)
in if d==0
then -- Discriminant is zero, (single) root is real
Root $ realpart :+ 0
else
if d<0
then -- Discriminant is negative, roots are complex
Roots (realpart :+ complexpart) (realpart :+ (-complexpart))
else -- Discriminant is positive, all roots are real
Roots ((realpart + dpart) :+ 0) ((realpart - dpart) :+ 0)
のlet ~ in みたいなのを
rootsInternal q d
| d==0 = ...
| d<0 = ...
| otherwise = ...
みたいな書き方の時にもやりたいんです
576:デフォルトの名無しさん
20/11/09 19:58:42.43 .net
おっと無用な改行が一々入っちゃった。。。
577:デフォルトの名無しさん
20/11/09 20:20:48.18 UhW/CkjO.net
>>569-570
where で出来なかったっけ?だめだったかな?
578:デフォルトの名無しさん
20/11/09 21:00:20.89 .net
あ、できました。
お騒がせしました(////)
579:デフォルトの名無しさん
20/11/11 19:20:13.76 qheOKxfd.net
正格評価について質問です
ひとつの引数しかない関数 f を正格評価するときには
f $! x
でよいようですが2引数の場合はどうするんですか?
( f $! x ) $! y
で x, y を先に展開してくれますか?
良さげなんですがどう確かめたものやら
なんか正格評価と遅延評価で格段に計算量が変わる f の例ってありますか?
580:デフォルトの名無しさん
20/11/11 21:38:04.29 TR1bVb0l.net
遅延評価がなくてもGCはメモリ解放を遅らせている
GCをいじるにはIOが必要
$!を使うのにも少なくともモナドが必要と考えるのが自然なのでは?
x' <- return $! x
y' <- return $! y
return $! (f x' y')
581:デフォルトの名無しさん
20/11/11 22:07:05.86 F87BSTFR.net
>>574
そうなんですか?
とりあえずモナドで試してみます
兎にも角にも正格評価と遅延評価でこんなに計算の回数が違ってくるってのなんかご存知ないですか?
例えばdpの例でFibonacciを
f 0 = 0
f 1 = 1
f n = (f $ n-1) + (f $ n-2)
と
f' 0 = (0,1)
f' n = (a+b,a) where (a,b) = f' (n-1)
f = fst . f'
で比べると目に見えて計算量が違うみたいな奴で「正格評価が効いてる」って目に見えてわかるような例があるとありがたいんですが
582:デフォルトの名無しさん
20/11/12 14:57:12.09 +Y5HOlnE.net
正格評価と遅延評価で計算量が変わるといえばtaraiじゃね?
583:デフォルトの名無しさん
20/11/12 23:16:18.57 G64JuFLE.net
⊥になるものでいいじゃん
584:デフォルトの名無しさん
20/11/13 06:27:56.29 ewlhvLCU.net
trace や unsafePerformIO で評価順を調べられないかな
585:デフォルトの名無しさん
20/11/13 12:04:46.50 oAmrFI5R.net
みなさん情報ありがとうございます
今んとこヒマな時にやってみた実現は
cube x = x*x*x
a x = case x of
0 -> 0
1 -> 1
_ -> ( a $ x -1 ) + ( a $ x - 2 )
main = do
tA <- getCPUTime
print $ cube $ a 38
tB <- getCPUTime
print $ tB - tA
と
print $ cube $ a 38 → print $ a 38
の比較
結果
----
59722225363795389930809
3801127096000
----
39088169
3514055718000
この程度だとコンパイラが勝手にメモ化してくれるようで差がでないorz
まだタライとかは試して見てません
取り急ぎご報告まで
586:デフォルトの名無しさん
20/11/16 23:33:39.07 bCg5e61i.net
>>573
もうとっくに解決したかもしれませんが、評価の順は trace 関数でも確認できます。
import Debug.Trace
g :: Int -> Int -> Int
g x y = trace ("g") (x + y)
main :: IO ()
main = do
let a = trace ("a") 1
let b = trace ("b") 2
let c = (g $! a) $! b
putStrLn $ show c
これを実行すれば、b a g 3 の順に出力されます。
正格評価されていると言えます。
ちなみに、($!) を ($) に変えれば、g a b 3 の順に出力されます。
587:デフォルトの名無しさん
20/11/18 01:05:30.21 VzwFaHaO.net
>>580
イヤ、まだ奮闘中です
おぉ、そんな便利なものが
使ってみます
588:デフォルトの名無しさん
20/11/21 23:31:14.57 ak7brOTq.net
Haskellはライブラリの中身を覗くと
Template Haskellを駆使した
グッチャグチャの実質別言語みたいなコードがザラなのがなぁ・・・
水面下の白鳥状態じゃねーか
589:デフォルトの名無しさん
20/11/22 16:59:26.57 gt3QNmmg.net
ゴミライブラリ使うのやめて良いやつ作って公開してくれ
590:デフォルトの名無しさん
20/11/22 17:19:45.03 MRtbpg3I.net
在学中か学校出たての経験浅い奴しか担い手がいないのだろうからそんなもんなんだろう
純粋関数型言語は学生がかかるはしかみたいなもので
やがて計算機科学の現状に絶望し去ってゆく
現在のコンピューターは手続き型に最適化されているのだ
591:デフォルトの名無しさん
20/11/22 18:37:00.71 36XuvgN2.net
単純に関数型言語がわかる人が少なすぎるからじゃないの?
592:デフォルトの名無しさん
20/11/22 20:14:41.06 .net
居飛車党と振り飛車党の闘いは続く
593:デフォルトの名無しさん
20/11/22 23:16:18.31 b60g3zenS
みずほが週休3日・4日を導入、副業もオッケーに!ただし給料は80%、60%に下がるが、あなたならどうする?
URLリンク(www.excite.co.jp)
みずほFG 週休3~4日制導入へ 新型コロナで働き方見直し
URLリンク(www3.nhk.or.jp)
副業OK時代!初心者に人気の副業を試してみて…メリット・デメリットとは
URLリンク(news.yahoo.co.jp)
「労働時間の見直し」に先鞭をつけた みずほフィナンシャルグループ
URLリンク(blogos.com)
給料ダウンの危機を副業でカバーしたい…副業している人はどんな仕事でいくら稼いでいるの?
URLリンク(news.yahoo.co.jp)
副業を会社に報告しない理由TOP3、3位会社が禁止している、2位告知されていない、1位は?
URLリンク(dime.jp)
副業年収1億超のmotoさんに聞いた!「本業」で成果を上げて自分の市場価値を高める方法
URLリンク(ddnavi.com)
フリーランス向け報酬即日払いサービス『先払い』が大規模リニューアルし正式リリース
URLリンク(prtimes.jp)
国内最?級!副業・フリーランスエンジニアに特化した、仕事探しの求?アプリ
『doocyJob(ドーシージョブ)』、iOS版アプリを2020年10月6日(?)リリース
URLリンク(prtimes.jp)
594:デフォルトの名無しさん
20/11/23 02:58:53.25 v8DPq2Nr.net
イヤ、まぁ純粋に速度とか効率とか考えたら手続き型言語の方が優位なのはその通りでしょ?
だって現在の計算機がノイマン型の手続き型の処理をするために設計されてるんだから
そりゃバリバリにチューニングしたら手続き型言語には絶対勝てない
595: その時代時代の最新の計算機の性能をフル活用しないとできないような処理は当面関数型言語の出番は回ってこない しかしそこまでの処理でないならやはり関数型言語の活躍できる場面も出てはくるだろうけど、しかし例えそうなったとしても手続き型言語も関数型言語も両方臨機応変に使いこなせるようになるとなると中々難しいから、結局どちらか選ぶなら手続き型言語という事になってしまう しばらくは関数型言語が実務の場面でバリバリ使われるようになるのは中々難しい 当面研究者とか、サンデープログラマーの趣味の世界でしか出番ないかもしれない
596:デフォルトの名無しさん
20/11/23 03:10:25.23 i6Fa5mHr.net
並列並行処理を型で表せる辺り、強力なんだけどなぁ
597:デフォルトの名無しさん
20/11/23 03:19:37.79 vzAx9TtB.net
Reditを見てると、Haskellerの求人も結構あるんだが
598:デフォルトの名無しさん
20/11/23 12:02:25.91 B9DSaA3p.net
居飛車と振り飛車というのは危機感が足りない
ガソリン車と電気自動車だ
個人の就職じゃなくて会社が丸ごと潰れるリスクを想定するための研究だよ
599:デフォルトの名無しさん
20/11/23 13:19:57.85 XIoHPhIo.net
一句できた!
『次に来る』
言われ続けて
数十年
(来ない)
600:デフォルトの名無しさん
20/11/23 13:27:42.48 izonrGpC.net
近未来
今となっては
古臭い
601:デフォルトの名無しさん
20/11/23 13:29:17.88 XIoHPhIo.net
>>593
いいね!
602:デフォルトの名無しさん
20/11/23 14:40:17.74 B9DSaA3p.net
新しいなんて嘘つくより古いものは古いものとして扱う歴史や古文の方が正しい
603:デフォルトの名無しさん
20/11/23 20:51:18.66 .net
関数型言語を処理するために設計されたコンピュータってどんな構造なんだろ
604:デフォルトの名無しさん
20/11/23 21:33:53.00 B9DSaA3p.net
みんなが数学好きで自己啓発嫌いなのは処理速度じゃなくて
嘘をつかないかどうかの問題
605:デフォルトの名無しさん
20/11/24 01:11:11.02 wCic/rFb.net
>>596
LISPマシンというものがかつてありましたなあ
606:デフォルトの名無しさん
20/11/24 03:49:22.53 EBaS3Lgi.net
JAVAチップが実現されてればスタックマシンだからFORTH最強だったのでは
607:デフォルトの名無しさん
20/11/24 21:00:48.17 BgPUrN9t.net
速度は実はそこまで重要じゃない
飛行機からメンテナンスハッチ取り除いて何kg軽量化しましたって言ったところで、仕事好き定量評価好きなにわかが、わかりやすい数字見て喜ぶだけで、実際はそんな嬉しい話じゃない
というかそもそももっと遅いスクリプト言語は流行ってるし
608:デフォルトの名無しさん
20/11/24 21:12:41.51 .net
Haskell でゲーム開発したいんですが
FRP は死滅しちゃったの?
609:デフォルトの名無しさん
20/11/24 21:44:37.33 2dUwtFIm.net
>>601
死滅の意味がよく分からんが、問題なく使える。
stackageにもあるでしょ。
それはそうと、なんで初めから難しいFRPを使おうとするの?
普通に素直に設計して作ってみればいいのに。
610:デフォルトの名無しさん
20/11/30 15:39:12.43 nSv/4rn0.net
bind演算子の名前の由来ってなに?
なにも束縛してなくね?
611:デフォルトの名無しさん
20/11/30 17:26:29.13 +w97lXkL.net
a >>= b
がdo記法で
do
x <- a
b x
みたいになるからじゃね?
612:デフォルトの名無しさん
20/11/30 21:06:13.38 qo5X+4ip.net
(>>) これも bind と言うよ
613:デフォルトの名無しさん
20/12/02 00:25:53.39 E6FeESB6.net
ここで聞いていいのかわからないけど…
Nixのいいチュートリアルとかってある?
614:デフォルトの名無しさん
20/12/04 21:16:59.61 kdWDDBYk.net
これとかどう?
URLリンク(github.com)
615:デフォルトの名無しさん
20/12/05 12:39:37.62 Na39OKS5.net
ブログ書いてたら彼女と無料で海外留学という名のデートに行けた話【影響力やばい】
URLリンク(www.youtube.com)
若いうちから人を雇ったり、任せるクセをつけるべき理由とは?
URLリンク(www.youtube.com)
【対談】インフルエンサーマーケティングに300万円突っ込んでみた結果...
URLリンク(www.youtube.com)
収入を上げたければ、自分の影分身を作るべし
URLリンク(www.youtube.com)
勉強のために10日間で21個のアプリを作った話【初心者時のプログラミング学習】
URLリンク(www.youtube.com)
学校では教えてくれないことの中にはお宝が眠っている
URLリンク(www.youtube.com)
ブロガーからステップアップしていくために必要なスキル
URLリンク(www.youtube.com)
616:デフォルトの名無しさん
20/12/05 23:01:31.80 gIoCKCst.net
>>607
すごい良さげ。ありがとう
617:デフォルトの名無しさん
20/12/05 23:45:36.72 gZAhFzLL.net
>>608
すごい良さげ。ありがとう
618:デフォルトの名無しさん
20/12/06 02:18:39.34 HA18eG30.net
>>608
グロ
619:デフォルトの名無しさん
20/12/08 09:15:41.98 VKXi32Vk.net
実際にちょっとしたプログラム書いてみると
メモリ周りの最適化が困難なんだよなこの言語。
しかも最適化の方向性がアルゴリズムの改良ではなく
言語特有のボトルネックの回避がメインになるから
コードを見ても最適化の意図が分かりにくくて
一見無駄に冗長に記述してるだけに見えるコードが出来上がる。
620:デフォルトの名無しさん
20/12/08 11:08:46.52 EAPrHNYX.net
最適化の意図なんてPythonと同じでいい
ライブラリは全部Cで書いてmainだけHaskellで書け
621:デフォルトの名無しさん
20/12/08 12:02:52.73 mZ7rlOd+.net
一時期あんなにモナドの記事とか書かれまくったのに、最近盛り上がりに欠ける
Haskell製アプリも企業が採用したって話もほとんど聞かないけど、気のせい?
尖ったところで使われてるんかな
622:デフォルトの名無しさん
20/12/08 13:07:23.14 EAPrHNYX.net
言語関係なく企業が作ったアプリを買ったことがほとんどない
個人が書いた本を買うことはある
623:デフォルトの名無しさん
20/12/08 13:30:45.48 xvXTXIvz.net
まぁなんだかんだHaskellは実用性というより、やはり数学研究の一貫の色合いが強いからなぁ
624:デフォルトの名無しさん
20/12/08 13:52:48.29 CqCSsxMG.net
一環では?
数学の前に国語の研究をしたほうがよいのでは?
625:デフォルトの名無しさん
20/12/08 15:02:11.16 xvXTXIvz.net
お前はまず自分の人間性を見直せ
煽りじゃなくマジで
626:デフォルトの名無しさん
20/12/09 01:52:25.38 6n7tUtuW.net
Haskell自体は面白くて本や記事も読むけど、なんか書く気起きないんだよな
でも他の言語で関数型由来の機能が追加されたときに「あ、これHaskellでやったところだ!」ってなれる
627:デフォルトの名無しさん
20/12/17 17:53:27.84 9eI2x+Uu.net
Haskellでx = x + 1をIORef使わず擬似的に再現。
(実際には代入では無く、結果をラムダ式の同名の変数に渡してるだけ)
main = do let x = 0
print x
x <- inc x
print x
x <- inc x
print x
inc n = return (n + 1)
モナド式の書き方だとこうなる。
main = do let x = 0 in print x >> inc x >>= \x -> print x >> inc x >>= \x -> print x
inc n = return (n + 1)
さらに>>=演算子を()で囲んで関数にするとこうなる。
main = (>>=) ((>>=) (do let x = 0 in print x >> inc x) (\x -> print x >> inc x)) (\x -> print x)
inc n = return (n + 1)
628:デフォルトの名無しさん
20/12/17 17:53:45.49 9eI2x+Uu.net
モナド無しだけど、Cで再現するとこんな感じ。(スタック消費するけど)
#include <stdio.h>
int inc(const int);
int f(const int);
int main(void)
{
const int x = 0;
printf("%d\n",f(f(x)));
return 0;
}
int inc(const int x)
{
return (x + 1);
}
int f(const int x)
{
printf("%d\n",x);
return inc(x);
}
629:デフォルトの名無しさん
20/12/18 19:59:30.35 PXMujPNr.net
目的が実用だろうが研究だろうがIORefは使っていいぞ
IORefは手段なので、具体的な目的に依存しない
630:デフォルトの名無しさん
20/12/19 08:53:57.33 56QZYgov.net
気持ちはよくわかる。自分も初めてdo式の定義を見た時、おぉぉぉとなった。
というわけで、いつdo式パラダイスが登場したのかアヒル体験してみた。
[When was do-notation introduced?](URLリンク(www.reddit.com))
> Haskell 1.3 adopted Jones’s “do-notation,” which was itself derived
from John Launchbury’s paper on lazy imperative programming (Launchbury, 1993).
自分の場合、Haskellを知る前に、Moggi大先生の論文体験を一撃で敗退した時に
おぉぉぉした覚えがある。
* Notions of computation and monads
in [Eugenio Moggi Publications](URLリンク(person.dibris.unige.it))
宗教上の理由で、シーケント図が書かれた書物体験はできないが、幸いなことに、
最初のシーケント図にdo式らしきものが書いてある。ナウなヤングの言葉では
次のようになると思う。
``` haskell
kleisli_extension :: (Monad t) => (a -> t b) -> (t a -> t b)
kleisli_extension f c = do
x <- c
f x
```
今も論文に何が書かれているかわからないが、その時は、<em>おぉぉぉ、
プログラミング言語って数学的に捉えられるんだ</em>体験をした記憶がある。
一般に、紙上のプログラミング言語と実働するものとの間には万物の長城が
あるので、Haskellのdo式もすごい発明と思うが、その技法の骨子は、既に
[同時多発的](URLリンク(www.youtube.com))に発見されて
いたのかもしれない。歴史絵巻体験では、
[A History of Haskell](URLリンク(misreading.chat))も面白かった。
631:デフォルトの名無しさん
20/12/20 18:18:16.88 FMam64CT.net
ネタを拝借して、次のコードを考える。
``` haskell
inc :: (Applicative f) => Int -> f Int
inc n = pure (n + 1)
lhs :: (Int -> () -> String) -> Int -> IO String
lhs dump x = do
y <- inc x
z <- print y
pure $ dump y z
rhs :: (Int -> () -> String) -> Int -> IO String
rhs dump x = inc x >>= \y -> dump y <$> print y
lhs ((.) show . (,)) 123 >>= print
rhs ((.) show . (,)) 123 >>= print
lhs (const . const "hello") 123 >>= print
rhs (const . const "hello") 123 >>= print
```
632:デフォルトの名無しさん
20/12/20 18:18:58.94 FMam64CT.net
IOモナドを恒等モナドに差し替えて、Rに移植する。
``` {r raskell}
do = pure = id = function (a) a;
const = function (a) function (ab) a;
`%.%` = function (bc, ab) function (a) bc (ab (a));
`%$%` = function (ab, a) ab (a);
`%>>%` = function (a, ab) ab (a);
inc = function (n) n + 1;
caty = function (a) cat (a, "\n", sep = "");
lhs = function (dump) function (x) do ({
y <- inc (x);
z <- caty (y);
pure %$% dump (y) (z);
});
rhs = function (dump) function (x) {
inc (x) %>>% (function (y) dump (y) %$% caty (y));
};
lhs (function (y) function (z) list (y, z)) (123) %>>% print
rhs (function (y) function (z) list (y, z)) (123) %>>% print
lhs (const %.% const ("hello")) (123) %>>% print;
rhs (const %.% const ("hello")) (123) %>>% print;
```
Rは関数の引数を問答無用に遅延評価するので、最後の`rhs`だけがHaskellと
異なる動作をする。Rの遅延評価の例としては煩雑過ぎるが、HaskellのIOモナド
とサイドバイサイドに比較できる例になっている。
633:デフォルトの名無しさん
21/01/05 09:39:14.86 b/Fw/Z0P.net
ふと思った。
a型の2次元配列が必要になった時、
[[a]] や Array (Int, Int) a ではなく、
(Int, Int) -> a が真っ先に思い浮かぶなら、
そいつは関数型にどっぷりハマってるな、と。
634:デフォルトの名無しさん
21/01/08 14:54:16.81 QDat+Qoy.net
関数型は並列処理に強いという話を聞くけど
fpgaの高位合成がC言語で行われている理由は何ですか?
haskellでの高位合成やgpgpuはどうなっていますか?
実用されていますか?
635:デフォルトの名無しさん
21/01/08 15:09:45.01 QDat+Qoy.net
Haskellの人気は横ばいまたは下降気味。
なぜ未来であるはずのHaskellは勢いを持たない?
実際使ってる人達の印象はどうなの?
URLリンク(www.reddit.com)
URLリンク(trends.google.com)
URLリンク(insights.stackoverflow.com)
636:デフォルトの名無しさん
21/01/08 15:22:31.00 QDat+Qoy.net
Haskellはアカデミックな言語だっていうけど
アカデミックな人がやることが多い機械学習でPythonが伸びた
並列処理に強いなら機械学習の行列処理がHaskellで行われても良かったんじゃないの?
637:デフォルトの名無しさん
21/01/08 18:33:26.91 rDTYcDTI.net
Haskellは並行並列を楽に書けるのであって速く書くのに向いているわけではない(滅茶苦茶向いていない訳でもないがハードウェアに近い組には速度で勝つのは大変)
そしてDNNは内部処理がテンソル演算でこそあるけどインターフェイスでそこまでむき出しのテンソル演算をするのは多くない
なによりアカデミックは一枚岩ではなく当然色々幅が広くて
Haskellがアカデミックと呼ばれる所以は言語処理系や型理論、その実装の分野
並行並列が楽に書けるってのはその流れからくる、関数の純粋性とソフトウェアトランザクショナルメモリの成果
機械学習系の源流になる内の画像処理系ではC++やmatlabが、統計系はRやmatlabが使われててnumpyと共に徐々にPythonに移行してきた
ちょっと下のレイヤーのBLASやシミュレーションではC++とFortran、後にGPGPUの独擅場で今ではPythonから呼ばれる形で使われてる訳だ
638:デフォルトの名無しさん
21/01/09 00:06:52.64 cFb9Tw8T.net
機械学習はどっぷり工学分野だからアカデミックという印象は少ないイメージあるが
639:デフォルトの名無しさん
21/01/09 16:47:47.44 gjIQ6YZR.net
haskellについて調べてるんだけど
関数の合成は関数Aの返値と関数Bの引数の型が一致するとかの条件が必要?
解説記事に「関数はファンクタです」とか書かれてるんだけど
任意の関数を合成できるわけじゃないよね?
640:デフォルトの名無しさん
21/01/09 17:24:37.63 Xoihvk5Y.net
>>632
関数合成のシグネチャを見れば分かる
(.) :: (b -> c) -> (a -> b) -> a -> c
"bからcへの関数"と"aからbへの関数"を受け取り、"aからcへの関数"を返す関数が関数合成
641:デフォルトの名無しさん
21/01/10 13:23:32.27 /oGn2fPm.net
・Functorは高階カインドのクラスです
・二変数の型構築子(->)を部分適用したものがFunctorのインスタンスになります
この説明を省略したら意味がわからないよね
642:デフォルトの名無しさん
21/01/11 01:34:20.58 OwjnhqSv.net
超大作過ぎるけど
[Entropy and Diversity](URLリンク(golem.ph.utexas.edu))
643:デフォルトの名無しさん
21/01/11 11:54:49.85 TrSsUTEh.net
>>632
関数合成可能性の話と関数が関手であることは全く関係ないぞ
644:デフォルトの名無しさん
21/01/11 13:43:32.73 nJc/cTVc.net
Haskell 圏論
=====================
関数 射
Functor 関手
Reader r Hom関手
645:デフォルトの名無しさん
21/01/11 16:14:02.10 nJc/cTVc.net
H本終えたくらいの初心者が、中級上級それ以上を目指すためのロードマップって大体こんな感じ?
わたしは全部マスターしたわけじゃなくて、界隈でよく聞くのでなんか重要そうくらいのノリw
中級
・Freeモナド
・Profunctor optics
・コモナド
・Custom Prelude
上級
・型レベルプログラミング
・Extensible Effects
・Indexed Monads
・Template Haskell
646:デフォルトの名無しさん
21/01/11 23:19:18.98 N3ahWSVP.net
まず何より先にアプリ作ろうよ。
先人たちはアプリを作りまくる過程で、
役立つテクニックや概念を編み出してきたのだから。
647:デフォルトの名無しさん
21/01/12 00:18:20.62 5J1t5Bxr.net
Haskellは哲学であり、哲学からは何も生まれない
648:デフォルトの名無しさん
21/01/12 01:04:23.78 exO7rD20.net
>>639
ここでの問題はHaskellの鉄人になるためのロードマップであって、
Haskellでアプリを作れるようになるためのロードマップではない
649:デフォルトの名無しさん
21/01/12 01:51:40.85 pX8tczV2.net
>>641
そうか、余計な事だった、すまない
650:デフォルトの名無しさん
21/01/12 09:05:11.74 IiGdAufF.net
哲学からは法が生まれますが…
651:デフォルトの名無しさん
21/01/12 10:08:30.41 fccMRI32.net
何かを生まなければならないというのは道徳か?
その道徳から全てが始まるのか
652:デフォルトの名無しさん
21/01/13 04:05:16.97 A4IGUr+p.net
オタクのこういう会話クソキモい
653:デフォルトの名無しさん
21/01/13 10:09:05.37 o5CAyZYI.net
キモいという感情から
感情と知性の分断が生まれる
654:デフォルトの名無しさん
21/01/13 10:21:18.95 8kUJEegp.net
Haskell でカッコよく速いプログラム書きたいんですが、どう言う分野が向いてますか?
655:デフォルトの名無しさん
21/01/13 21:12:21.98 DinE+zFR.net
>>647
パズルソルバー
656:デフォルトの名無しさん
21/01/13 22:41:38.73 CNkC++cr.net
感情は先入観から生じ
先入観を克服することで知性に至る
657:デフォルトの名無しさん
21/01/14 00:13:44.79 JY+VfWVO.net
でも先入観のメリットはスピードだから
速度の最適化みたいな建前を用意すれば知性と知性の対等な関係にはなる
建前はキモいとか本音がカッコイイとか言い出さない限り
658:デフォルトの名無しさん
21/01/14 07:11:45.05 UC/QgsCt.net
感情のための知性が工学
知性のための知性が理学
659:デフォルトの名無しさん
21/01/14 08:24:32.45 mp+NLhBe.net
なんかやたらポエムを書きたがるレスが増えたな
660:デフォルトの名無しさん
21/01/14 10:42:33.32 ApYxPV7C.net
音やリズムをデザインしてるのか
音読できない言文不一致言語があれば、デザインと論理的構造を分離できそう
661:デフォルトの名無しさん
21/01/15 04:12:13.96 NAFJshBl.net
これ意見割れてるけどどっちが正しいの?
有識者諸君のご意見を伺いたい
URLリンク(www.quora.com)
662:デフォルトの名無しさん
21/01/15 10:43:33.32 l3Q+U92p.net
関数型を信じるというよりオブジェクト指向を疑うべき
オブジェクト間の通信がただの関数呼び出しから軽量スレッドに変わったらどうなるか等
663:デフォルトの名無しさん
21/01/15 20:09:59.52 SSKXVcKf.net
>>655
重たくなる。
664:デフォルトの名無しさん
21/01/16 10:01:48.97 fPN57ROF.net
fix関数は least-defined な不動点を見つけるそうだけど、
この least-defined ってどういう意味?
665:デフォルトの名無しさん
21/01/16 10:43:22.09 lq2o0P8I.net
おれの先入観によるとポインタの循環の周期が最小
666:デフォルトの名無しさん
21/01/20 07:45:01.78 0A31ygkk.net
多分できないんだろうなと思いつつ質問です
あるページで乱数をいっぱい調達する方法でこんなのありました
randIntsList = let
getOne rec = ( return . ( : rec ) )
=<< ( randomIO :: IO Int )
in iterate ( >>= getOne ) ( return [ ] )
main = do
a <- ( return . head ) =<< randIntsList !! 100
print a
コレはもちろんうまく行きました
でもコレちょっと不愉快です
IO [ Int ] とかで例えば
randInts :: IO [ Int ]
randInts = do
hd <- ( randomIO :: IO Int )
tl <- randInts
return $ hd : tl
main = do
a <- ( return . head ) =<< randInts
print a
とかであらかじめ使う数を指定しないで好きなだけとってくるとかできないもんでしょうか?
上のはGHCで参照すると実行時エラー出ます
667:デフォルトの名無しさん
21/01/20 14:24:39.71 7SUaJKsz.net
ついさっき関数的プログラミングの話題してたが
やっぱり通じないな
関数?そりゃ関数くらい普通に書くよねw
副作用?必要なら出ないように書けばいいんじゃないの?どうでもよくない?
純粋関数の考え方?そんなのいらないよねw
部分適用?今までそんなの必要になったことないなあw そんなの何に使うんだ?
まあ言われてみれば誰にでもわかるような利点を提示できないってのは確かにあるが・・
利点がないなら好みの範囲で片付けられちゃったな
668:デフォルトの名無しさん
21/01/20 15:57:32.54 ztk5BuHj.net
いらないと思う人は使わなければいいし気にしなければいいってだけだよね
669:デフォルトの名無しさん
21/01/20 16:39:30.61 IzsyJlfZ.net
>>659
これでどうかな?
randInts2 :: [IO Int]
randInts2 =
iterate ( >>= const (randomIO :: IO Int) ) (randomIO :: IO Int)
main :: IO ()
main = do
a <- head randInts2
print a
670:デフォルトの名無しさん
21/01/20 17:07:44.96 aAR5bcpB.net
>>660
いわれてみればhaskell触るまでこういう特徴が泣くほどうれしいなんて思ってなかったなぁ……
671:デフォルトの名無しさん
21/01/20 17:39:40.94 kKr2IDUq.net
>>660
利点を提示っていうかLispとHaskellの違いを提示する必要がある
Lispの利点を再現するだけならPythonで十分な気がする
しかしHaskellを再現できるものがまだ出てこない
それは関数型じゃなくて静的型の説明をしないと意味が分からないと思うけど
672:デフォルトの名無しさん
21/01/20 18:38:17.88 apYLuAz7.net
>>662
ありがとうございます
そうなんです
今のところそれしか解決策ないんです
しかし希望では IO [ Int ] であって欲しいんです
イメージとしてはこうです
ある関数 f があって乱数で挙動が変わって欲しい
もちろん最終的にはIOモナドを使わないとしょうがない
しかし色々いじってる段階ではモナド被せないで代わりに擬似乱数無限配列 psuedRand :: [ Int ] みたいなのを食わせて
f a b c psuedRand
みたいに呼び出して色々頑張って、最後の最後にIOモナドで実地に
( return . f a b c ) =<< realRand
に切り替えるみたいな事ができないかなと思ったんです
f が使用する乱数がある程度わかるので別に無限列でなくてもいいっちゃいいんですけど
今一歩モナドに包まれてる関数いっぱい出てくるの好きじゃないんですよ
通のホムペとか見てるとむしろバンバンモナドでくるんどいた方がいいみたいなのもみるんですけどねぇ
673:デフォルトの名無しさん
21/01/20 18:57:39.14 IzsyJlfZ.net
>>665
そうなのかあ。
すまない、俺では力不足のようだ。
674:デフォルトの名無しさん
21/01/20 19:04:15.17 apYLuAz7.net
>>666
いえいえ、ありがとうございます
考えていただいて感謝です🙏
675:デフォルトの名無しさん
21/01/20 20:02:19.54 kKr2IDUq.net
headやtailの戻り値の型はIOではないって宣言してるから
リスト処理中にrandomIOができなかったとしても不思議ではない
型を宣言するってそういうことよ
676:デフォルトの名無しさん
21/01/20 21:15:09.40 jArj32vs.net
>>665
やりたい事の本質がいまいち分かりません。
2点確認します。
ひとつめ。
結局のところ今は [a] 型の乱数を返す関数を作りたいのでしょうか。
それとも、IO [a] 型の乱数を返す関数を作りたいのでしょうか。
はたまた、両方でしょうか。
ふたつめ。
開発環境では
> f a b c psuedRand
本番環境では
> ( return . f a b c ) =<< realRand
という事でしょうか。
前者は純粋関数の式、後者は IO モナドを伴う式です。
これは、本番環境で IO モナドな関数を、開発環境では純粋関数で開発するという事ですよね。
開発環境を本番環境にする際には、後者の式を呼び出している外側の関数も、
純粋関数から IO モナドに書き換えるのでしょうか。
あまりお勧めしません。
本番環境で IO モナドな関数は、開発時も IO モナドで開発&テストした方が良いと思います。
環境が違ってもインターフェース(型シグネチャ)はそろえた方が良いです。
事情がおありなので、あくまで私は勧めないというだけですけど。
677:デフォルトの名無しさん
21/01/20 21:21:29.93 apYLuAz7.net
>>668
まぁそうですね
できんもんはできんのでしょうね
ただ出来るか出来ないかの判定がまだまだ自分の実力不足でできないのか、実際禁止されててできないかのか判断がつかないんです
>>669
やはりそうなんでしょうね
まだまだ初心者でいまひとつモナドで包まれてるの馴染みがないので避けれるなら避けたいと思ってしまいます
この場合はモナドで最終的にくるむなら避けられても避けるべきではないのでしょうね
678:デフォルトの名無しさん
21/01/20 21:52:28.04 kKr2IDUq.net
>>670
型を書かない言語も普通に存在するので、型を無視する方法があってもそれも不思議ではない
679:デフォルトの名無しさん
21/01/20 23:15:01.74 Sb+ElJSJ.net
>>671
まぁ今回のは諦めます
出来るのなら見つけたホムペの人が紹介してくれてただろうし
680:デフォルトの名無しさん
21/01/21 00:38:31.39 HkuQh/W6.net
>>660
副作用とか純粋関数の話は単体テストの話題と絡めたいね
それが通じなかったら知らん
部分適用というか高階関数の話は
コールバックとかイテレータのような「処理の抽象化」が
極めて書きやすくなるというような話でどうか
681:デフォルトの名無しさん
21/01/21 06:01:52.78 mwzMDOkA.net
Haskellで厳しく性能を最適化しようとすると
抽象的なところで実装を意識したコードを書くことになって苦労する
みたいなレビューがあった
Haskellはベンチ結果良いように見えて
その手の「実装を意識したコード」がベンチ用に書かれるからで
実際は割と遅めなんだな
682:デフォルトの名無しさん
21/01/21 06:07:07.88 LkrjH2wS.net
>>674
そのレビューのURLを貼っていただけないでしょうか
683:デフォルトの名無しさん
21/01/21 06:30:57.22 mwzMDOkA.net
URLリンク(stackoverflow.com)
この辺
> thanks for the link.
80 lines is what I called "low-level style of programming not much different than
programming in C itself." . "the higher level code",
that would be the "stupid" fmap (length &&& length .
words &&& length . lines) readFile.
If that was faster than (or even comparable to) C,
the hype here would be totally justified then.
We still need to work hard for speed in Haskell as in C, is the point.
>>612もそんなことをかいてる
684:デフォルトの名無しさん
21/01/21 06:38:11.58 mwzMDOkA.net
以下の厳密というのは遅延評価じゃなくするという事だろう?
しかも「プロファイルを作成して改善」は一度アプリを書いてから実行の様子を観察して最適化していくという事だろう。
抽象的にHaskellらしく書いていきなり速いというわけではないという事だ。
プロファイラーでボトルネックを特定して特殊なコードに変えていけば速くなる、と。
>はい、怠惰はおそらくナイーブなHaskellが遅い最大の理由であり、
最適化されたHaskellでさえ速度の点で信頼できない可能性があります。
そのため、パフォーマンスが重要なアプリケーションにはお勧めしません。
OCamlの方が適しています。繰り返しになりますが、
HaskellをBangPatternsなどで厳密にすることはそれほど難しくありません。
また、コードの読み取りや保守が難しくなることもありません。
したがって、パフォーマンスが望ましいが、遅いプロトタイプでも問題がない場合は、
Haskellが非常に良い選択です。うまく機能するものを一緒にハックしてから、
プロファイルを作成して改善します。
685:デフォルトの名無しさん
21/01/21 08:18:51.22 mwzMDOkA.net
こういう認識
・Haskellはコードだけでは最適化ポイントを見つけれない
・最適化したら変なコードになる
・普通のHaskellコードはベンチで他言語に惨敗する
686:デフォルトの名無しさん
21/01/21 09:21:08.07 mwzMDOkA.net
これも
・最適化の方法が処理系(GHC)次第で決まり、プログラマーの認識内に無い。
GHCに対してひたすらトライアンドエラー
687:デフォルトの名無しさん
21/01/21 21:44:08.46 AWFMWVQb.net
・Haskellが欲しかったポジションはなんかPythonにとられてしまった
688:デフォルトの名無しさん
21/01/22 00:20:12.86 IysdrbOG.net
HaskellとPythonは似ていないから両方使ってもDRYに違反しない
似たもの同士で馴れ合い、異質なもの同士を分断するやつは信用できないが
Pythonは似たもの同士でしっかり競争して生き残ったやつだから信用できる
689:デフォルトの名無しさん
21/01/22 01:34:45.31 Zh6FWeVu.net
pythonがなかったとしてもhaskellがそのポジションになることはなかっただろう
690:デフォルトの名無しさん
21/01/22 02:27:11.57 XLcorGPG.net
欲しかったHaskell
・型を最大限に活用、バグが無いことを保証しつつ自然にC言語並みの性能も出る
691:デフォルトの名無しさん
21/01/22 08:04:15.32 RWrydEj5.net
Haskellerのキモオタ「シグネチャァ」
692:デフォルトの名無しさん
21/01/22 12:35:37.28 Erx3tlcS.net
醜悪な表現が得意な奴って、綺麗な表現だとポエムとか言われる恐怖を煽られた結果なのかなと
ふと思った
693:デフォルトの名無しさん
21/01/22 18:29:59.60 WeFjBpWyB
デキる人ほどフリーランス化する?★働き方改革
URLリンク(www.youtube.com)
年収890万円以下は社会のお荷物★騙される労働者
URLリンク(www.youtube.com)
騙されたくなかったら勉強しろ★他人のルールは損をする
URLリンク(www.youtube.com)
底辺の99%は一生底辺★10年後が見えない同僚たち
URLリンク(www.youtube.com)
稼ぎたければ働くな★4千万円ぽっちも稼げないのはなぜ?
URLリンク(www.youtube.com)
サラリーマン思考では儲からない理由
URLリンク(www.youtube.com)
「頭使えよ貧乏人」に思う、寝てても金入るシステムを作る人
URLリンク(www.youtube.com)
694:デフォルトの名無しさん
21/01/23 13:17:02.46 u7XOzuV6.net
>>672
ListT を使えばと思ったけどだめだった。
・参考
URLリンク(blog.mudatobunka.org)
・残骸
695: module Rand2 where -- stack install list-t -- stack exec ghci import Control.Monad.IO.Class ( liftIO ) import ListT ( ListT, toList ) import System.Random ( Random(randomIO, randomRIO) ) t1 :: ListT IO Int t1 = return 3 t2 :: ListT IO Int t2 = liftIO (randomIO :: IO Int) t3 :: ListT IO [Int] t3 = repeat <$> t2 output :: ListT IO [Int] -> IO () output t3 = do li0 <- toList t3 print $ take 10 $ head li0
696:デフォルトの名無しさん
21/01/23 22:12:27.68 u7XOzuV6.net
>>687
できたー!
module Rand2 where
-- stack install list-t
-- stack exec ghci
import Control.Monad.IO.Class ( liftIO )
import ListT ( ListT, toList, cons, take )
import System.Random ( Random(randomIO) )
t2 :: ListT IO Int
t2 = liftIO (randomIO :: IO Int)
t3 :: ListT IO Int
t3 = do
x <- t2
cons x t3
output :: IO ()
output = do
li <- toList $ ListT.take 10 t3
print li
{-
*Rand2> output
[7616927328998369033,6970782903781268443,-1509938769401207081,-2789264750098693865,-6524417077297424569,8403979199680420436,-3097298192134792937,-2736699795503652525,-4754186463647322678,5658901448509988002]
-}
697:デフォルトの名無しさん
21/01/24 10:57:12.77 EEhZoft7.net
自分の理解が根本的に間違ってるかもしれんけど
haskellは宣言型で実効順序が定まっていないみたいな話を聞いたんだけど
do記法は普通に上から下に実行されるというイメージになるの?
main = do
x <- readLn
x2 <- readLn
こういう風に書いた場合、最初に入力したものがxに入り、その順番は入れ替えれないはず
do記法はほとんど命令型じゃないの?
IOモナドとかに入力されていくアクション列はその順番を入れ替えれないよね?
どんな感じでコーディングされてるか知らないけど
副作用があるところでは順番を入れ替えれないはず、即ち命令型と大差ないはず
698:デフォルトの名無しさん
21/01/24 12:14:30.84 3w4a632B.net
>>688
おお、できるんですか!?
すげー
残念ながらいまListT使えないので環境整理してやってみます
699:デフォルトの名無しさん
21/01/24 13:21:27.07 vsDmG4Mq.net
>>689
do記法という言語機能は、上から下への命令の実行を記述するものではない
モナドの組み合わせ方を宣言しているだけ
IOのようなモナドの定義に対してはたまたま命令型言語のようになるだけ
言語レベルで命令を上から下へ実行しているわけではない
700:デフォルトの名無しさん
21/01/24 15:49:32.04 EEhZoft7.net
じゃあ標準入力から来た文字列の1行目と2行目を分けて扱うにはどう書くの?
701:デフォルトの名無しさん
21/01/24 16:19:42.60 QSDOehpN.net
ListT.toListの引数には有限のリストしか渡せないんだろう多分
現に
li <- toList t3
print (take 10 li)
ではなく
li <- toList $ ListT.take 10 t3
print li
と書いてある
702:デフォルトの名無しさん
21/01/24 16:51:40.79 o8L11MsB.net
>>693
> ListT.toListの引数には有限のリストしか渡せないんだろう多分
> 現に
> li <- toList t3
> print (take 10 li)
> ではなく
> li <- toList $ ListT.take 10 t3
> print li
> と書いてある
確認したところ、おっしゃる通り、
前者では応答が返ってきませんでした。
(ListT.repeat でも同じ結果だったので、t3 が悪いのではないです)
> ListT.toListの引数には有限のリストしか渡せないんだろう多分
これで合っていると思います。
703:デフォルトの名無しさん
21/01/24 23:50:31.64 3w4a632B.net
やっぱり無理なんですかねぇ?
例えば以下は通るので ”IO 無限リスト” が原理的に無理なわけではないとは思うんですけど
list = return $ repeat '3'
main = do
x <- list
print $ take 10 x
何がどう違うもんなんでしょう?
704:デフォルトの名無しさん
21/01/25 09:17:23.58 xOoQiCMv.net
すいません
無限ランダム整数列の件ですが方法がありました
というかSystem.Randomの中に最初から用意されてました
自作でランダム有限列作っておられた方のブログ見つけたので無限列なんて用意されてないとすっかり思い込んでました
以下の方法で1~10の長さ100の乱数列が簡単に作れるようです
第一引数に値の範囲、第二引数に乱数の種を仕込みます
乱数の種は
mkStdGen :: Int -> StdGen
や
getStdGen :: IO StdGen
newStdGen :: IO StdGenSource
で作成すれば良いようです
乱数の型はIntだけでなくDoubleなどでも作れるようです
----
import System.Random
randomInts :: StdGen -> [ Int ]
randomInts = randomRs (1,10)
main = do
ris <- ( return . randomInts ) =<< getStdGen
print $ take 100 ris
705:デフォルトの名無しさん
21/01/25 09:36:17.94 lGPRZ7j1.net
種が IO だから、
randomRs の戻りは [a] なんだね
706:デフォルトの名無しさん
21/01/25 11:51:44.88 crCxtFmd.net
ライブラリは暗記ですが、数学は暗記ですか?っていう定番のあれだな
707:デフォルトの名無しさん
21/01/25 13:32:32.62 /TZZteD8.net
>>692
newStdGen :: IO StdGenSource
↑ワロタw
コピペするとよくあるわw
708:デフォルトの名無しさん
21/01/25 13:33:07.46 /TZZteD8.net
安価ミス>>696
709:デフォルトの名無しさん
21/01/27 00:16:50.20 UiZI3fhW.net
dp の質問です
haskell でdynamic programing する方法の例でFibonacci数列の計算を
fib = 0:1:( zipWith ( + ) ( drop 0 fib ) ( drop 1 fib ) )
で計算させるというテクニックを紹介しているページがあってなるほどなぁと感心しました
で同じテクニック使ってcomb6 !!i !! jが二項係数C[i, j]になる配列
comb6 = ( ( 1 : ( repeat 0 ) ) : )
$ zipWith ( zipWith ( + ) ) comb6 ( map ( 0 : ) comb6 )
を作ってみました
コレはうまくいきます
comb6 !! 2000 !! 1000
とかも一瞬で計算してくれます
でcomb7 !! i !! j が二項係数C[ i+ j, i ]となる配列comb7を
comb7 = ( ( repeat 1 ) : )
$ zipWith ( zipWith ( + ) )
( comb7 )
( tail $ map ( 1 : ) $ comb7 )
と定義してやってみると、compileまでは通るのですが実行comb!!1!!0すると<<loop>>と言われて止まってしまいます
しかし手計算で展開してみてもloopしてないと思うんですけどどこがおかしいのかわかりません
どなたかわかりませんでしょうか?
710:デフォルトの名無しさん
21/01/27 11:32:01.04 fGEABlaN.net
comb7 = x : xs
xs = zipWith f comb7 ys
ys = tail zs
zs = map g comb7
zs = map g (x : xs)
= g x : map g xs
ys = tail (g x : map g xs)
= map g xs
xs = zipWith f comb7 (map g xs) -- ここで(map g xs)のパターンマッチができない
711:デフォルトの名無しさん
21/01/27 12:36:29.90 UiZI3fhW.net
>>702
ありがとうございます
しかしどうもパターンマッチに失敗してるようではないようです
実際コンパイラは型推論に成功してるように見えますし、明示的に
comb7 :: [[ Int ]]
を入れてもダメです
実行時のエラーメッセージも
Non-exhaustive patterns
ではなく
prog : << loop >>
が表示されています
712:デフォルトの名無しさん
21/01/27 13:52:31.92 fGEABlaN.net
こういう時は自分の考えに自信を持つことも必要
誰かがエラーメッセージを見ている(または見ていない)のを見たからといって簡単に考えを変えない方がいい
713:デフォルトの名無しさん
21/02/01 00:47:55.98 TMv1Um3B5
個人開発のWebアプリがツイッター世界トレンド1位になったけどいろいろ辛かった話
URLリンク(vdeep.net)
【副業】個人アプリ開発の広告収入を公開します(?2020/11)
URLリンク(cranklog.xyz)
アプリ開発を個人で独学して収入を得る方法を現役エンジニアが徹底解説
URLリンク(yaba-blog.com)
【個人開発1年振り返り】リリースした7つのWebサービスの反省点と来年の活動について
URLリンク(yukio.site)
個人開発のアプリで稼ぐのはそんなに難しいのかな?
URLリンク(blog.httqs.com)
個人開発者(副業サラリーマン)のアプリ広告収入を公開
URLリンク(sastd.com)
アプリ開発は稼げない?よくある勘違いや言い訳を徹底批判してみる
URLリンク(apps.jp.net)
個人がアプリ開発で収入を得る方法は4つ。だが甘くない!
URLリンク(programming-school-hikaku.jp)
714:デフォルトの名無しさん
21/02/02 01:48:19.32 yyMOWUoH.net
fixの定義は fix f = let x = f x in x となっていますが、
この x 自体は再帰的に定義されていると言えますか?
715:デフォルトの名無しさん
21/02/02 16:19:31.38 ErrealWs.net
>>701
xs0 = repeat 1
xs1 = zipWith (+) xs0 (0:xs1)
xs2 = zipWith (+) xs1 (0:xs2)
xs3 = zipWith (+) xs2 (0:xs3)
こんな感じに個別に定義すれば確かに計算できるので、
comb7 !! 1 を計算するのにcomb7 !! 1 が必要だぞという点を
怒っているような気がするのだが確かなことは言えない、すまぬ
comb6 !! n は計算するのに comb !! (n-1) の情報だけで十分なところが違うので
716:デフォルトの名無しさん
21/02/02 17:58:42.89 AZLuBdJH.net
>>706
再帰的と言うのは木構造を想定している気がする
そのコードはグラフ簡約のためにそうなったので木構造でも再帰的でもないと思う
717:デフォルトの名無しさん
21/02/02 22:40:39.64 LQ6cge6d.net
>>707
ありがとうございます
私も多分それが原因かなと思い始めてます
一回目のcomb7 !! 1 と二回目では続く添字が! !!2 から !!1 に減ってるのですがHaskellはそんな事は勘案せずに「comb7 !! 1の展開の中にcomb7 !! 1が出てきたからアウト」と言ってるのかなと
つまりはこの手の二重漸化式はHaskellはそのままズバリでは読んでくれないんでしょうね
718:デフォルトの名無しさん
21/02/03 00:23:45.54 QKvl77B6.net
comb7 !! 1 を計算するには length comb7 >= 2 のようなものが必要だぞ
でも長さは1かもしれないからアウトという判断は正しい
オーバーランするよりよっぽどいい
719:デフォルトの名無しさん
21/02/03 14:08:13.61 mxabq2OH.net
求めてないかもですがこんなふうならかけますね。
module Main where
import qualified Data.Array.Unboxed as AU
main = do
print $ comb6 !! 2000 !! 1000
print $ comb7_1 !! 1000 !! 1000
print $ comb7_2 1000 1000 AU.! ( 1000, 1000 )
comb6 = ((1 : (repeat 0)) :) $ zipWith (zipWith (+)) comb6 (map (0 :) comb6)
comb7_1 = (repeat 1 :) $ ([ 1 .. ] :)
$ (map (\x -> scanl (+) 1 $ tail x) $ tail comb7_1)
comb7_2 :: Int -> Int -> AU.Array ( Int, Int ) Integer
comb7_2 ly lx = comb7_2_table
where
comb7_2_table = AU.array ( ( 0, 0 ), ( ly, lx ) ) $ concatMap(\i -> map (f i) [ 0 .. lx ]) [ 0 .. ly ]
f 0 x = ( ( 0, x ), 1 )
f y 0 = ( ( y, 0 ), 1 )
f y x = ( ( y, x ) , comb7_2_table AU.! ( (y - 1), x ) + comb7_2_table AU.! ( y, (x - 1) ))
720:デフォルトの名無しさん
21/02/04 23:30:39.86 OAJDFKMl5
サラリーマンの努力は資産にならない。
URLリンク(www.youtube.com)
ネットで稼げない残念な人の特徴
URLリンク(www.youtube.com)
【継続=勝利】続けているうちに、周りは勝手に消えていきます。
URLリンク(www.youtube.com)
【危険】今すぐ逃げろ!ヤバい会社の特徴10選。
URLリンク(www.youtube.com)
「ろくに勉強してこなかったバカ」が今日からすべきこと。
URLリンク(www.youtube.com)
バカは「必要努力量」を見誤る。
URLリンク(www.youtube.com)
721:デフォルトの名無しさん
21/02/04 22:24:53.84 w5MK0dgi.net
>>711
ありがとうございます
参考にさせていただきます
そうですね
もう一つ可読性が欲しい感じがします
元々の問題意識としては私は可読性の高いコードが要求されることが多いのです
例えばFibonacci数列であれば
f n = ( f $ n -1 ) + ( f $ n - 2 )
に可読性においてまさるものはないのですが、もちろんこれでは遅くて使い物になりません
なので実用性も多少はなりとも求めるならある程度は可読性を犠牲にせざるを得ないのですが、どういう方法がいいのだろうというのがテーマなのです
でたまたまFibonacciの場合に
f = 0 : 1 : ( zipWith ( + ) f $ tail f )
というのを見つけてコレ中々いいなと、dpで計算してるのに“メモ”をするための不要な手続きを書く必要がなく、Haskellの“call by need”の機能をうまく利用してdp計算させてるところにちょっと唸ったもので
でどれくらいコレでいけるのかなと二重数列をやってみたらうまくいかなくて、どうしたもんかなと
まぁコレはしょうがないのかもしれませんけど
722:デフォルトの名無しさん
21/02/05 00:47:44.85 hZ1aOePg.net
>>713
方向性違うかなと思いつつ書いたんですがやっぱり違いましたね。失礼しました。
今更どうでもいいですがちょっと間違えたので訂正だけさせてください。
comb7_1 = (repeat 1 :) $ (map (scanl (+) 1 . tail) $ comb7_1)
723:デフォルトの名無しさん
21/02/05 01:12:53.20 gzN36RyX.net
読むという目的
可読性の低いコードを、読むことなく却下するという手段
この目的と手段がすぐ入れかわってしまう現象もまた深刻な問題だ
724:デフォルトの名無しさん
21/02/05 06:11:52.56 5jF91Ui3.net
速さを求めてnconcみたいなもんだな
725:デフォルトの名無しさん
21/02/05 19:44:21.42 DBOaHn9B.net
>>713
その遅くて使い物にならない計算を、
可読性をあまり犠牲にしないで爆速にする方法に、
メモ化(memoization)というテクニックがあります。
(その代わり、当然メモリを使います)
メモ化関数 memoize が用意されていれば、
n 番目のフィボナッチ数を求める関数 fib は
次のように書けます。
-- メモ化
fib :: Int -> Integer
fib = fix (memoize . fib')
-- フィボナッチ計算の本体
fib' :: (Int -> Integer) -> Int -> Integer
fib' f 0 = 0
fib' f 1 = 1
fib' f n = f (n-1) + f (n-2)
メモ化関数を提供するパッケージは色々あります。
また、メモ化の仕組みの基礎や本質を学びたいのなら、
次のごく短いブログ記事がおすすめです。
URLリンク(kseo.github.io)
この記事の最後の fibMemo 関数について、
適当な小さな値に適用させたものを
自分でノートに展開してみるといいです。
726:デフォルトの名無しさん
21/02/05 20:00:27.08 DBOaHn9B.net
>>717
すいません。
肝腎の memoize 関数の定義を書き忘れました。
memoize :: (Int -> a) -> (Int -> a)
memoize f = (map f [0 ..] !!)
先に紹介した記事にこれを導く過程や、
より速くより一般化する方法を学びたい人へ向けた
URL紹介が載っています。
727:デフォルトの名無しさん
21/02/06 09:10:00.64 8eeMDweD.net
>>717
解説ありがとうございます
やはりメモ化するしかないんだと思います
問題はそれがプログラマが明示的に自分でやらないといけないのか、コンパイラが自分でやってくれるのかの差なんだと思います
Haskellは純粋なcall by nameではなく、call by needのシステムの中にメモ化を備えていてプログラマがメモ化するように書いてなくても勝手にメモ化できるものをメモ化してくれるのがすごいとこだと思うんですけど、例えば>>713の2番目の例で最初見た時「なんでこの定義式でメモ化が効くんだ?」とさっぱりわからなかったのが、実はHaskellのcall by needのシステムをうまく利用してるらしいとわかったのが最初なんです
で二重の漸化式だとうまくいかないなと
もちろん二重の全炊きでも上手くsuffixの取り方を変えたりすると同様の方法でメモ化できるんですけど、それでは結局「Haskellの機能を利用して明示的にメモ化を指定することなく高速化した」事にはなりません
まぁコレはしょうがないんでしょうね
どんな計算も常にメモ化して常に同じ評価式を2度扱う事を防いでたらそんなの逆に使い物になりませんからね
728:デフォルトの名無しさん
21/02/06 20:56:07.58 tGZHMqQF.net
Haskellが「ヤバそう」って偏見だけで敬遠されてるのかなしい…
同級生にも布教したい
729:デフォルトの名無しさん
21/02/06 21:00:00.51 xuEfQm7n.net
>>720
布教という言葉自体、独善的で押し付けがましく感じられる原因になってると思うよ。
相手がいやがらない程度にhaskellの良さや面白さを伝えてそれでも相手が興味をひかれないなら、それ以上はやめときな。
730:デフォルトの名無しさん
21/02/06 21:12:54.72 HlAr7yEc.net
>>719
今回の話の本質ではないので、へーそうなんだ、
程度に聞いてくれればいいのですが、
>>713 の2番目の例とは、
f = 0 : 1 : zipWith (+) f (tail f)
のことでしょうか。
もしそうなら、これはメモ化ではないですよ。
(このテクニックをなんと呼ぶのかは知りませんが)
メモ化というのは簡単にいえば、
関数の同じ引数に対する2度目(以降)の適用に備えて、
その引数に対する1度目の関数の値をその引数とペアにして
どこかにメモしておくことです。
ポイントは、2度目以降に備えることではなく、
引数と関数値のペアをメモしておくことです。
それを踏まえて、>>713 の2番目の例において、
では何が関数で、引数と関数値のペアはどこにメモされているか、
考えてみてください。
ただ、言葉の意味は時代と共に変化していくものなので、
今はこれも広義にメモ化と言うことになっているのでしたら、すいません。
私の方が勉強不足です。
731:デフォルトの名無しさん
21/02/07 08:28:27.99 kgbg5mk/.net
>>717の方がzipwith使ったものより読みやすくて遥かにいいな
こっちの書き方の方がもてはやされてほしいわ
732:デフォルトの名無しさん
21/02/07 10:58:25.84 nblMEePQ.net
久しぶりにHaskell(Servant)触ってみたけど
相変わらず呪文のようなテンプレートマクロとかコンパイル通すためだけの幽霊型とか表に出てきているのね
こういうの後ろに隠した実装がほちい(・ัω・ั)
733:デフォルトの名無しさん
21/02/07 21:10:43.40 B3cRggdVq
怒る・叱る文化は、安月給&長時間労働の証
URLリンク(www.youtube.com)
勉強しない社員★仕事のための投資をしない人たち
URLリンク(www.youtube.com)
バカが起業したんです★バカが社長になる過程
URLリンク(www.youtube.com)
時給10倍差は勉強と努力だけで差がつく★最大100倍差!
URLリンク(www.youtube.com)
ドリームキラー★夢の実現を応援する人、阻止する人
URLリンク(www.youtube.com)
年収1億円は「できっこない」をやり遂げた人★10万人、銀の盾来た!
URLリンク(www.youtube.com)
734:デフォルトの名無しさん
21/02/07 19:10:10.31 Ae+USThM.net
>>724
試しに作ってみればいいのでは?
そういう気に入らない幽霊型を
とりあえず1つだけ後ろに隠してみて、
使いやすいか試してみればいいと思う。
良さそうなら、ここや GitHub で提案するとか。
735:デフォルトの名無しさん
21/02/07 21:05:48.19 kgbg5mk/.net
Servant辛いから是非お願いしたい
736:デフォルトの名無しさん
21/02/08 03:22:56.40 lr3qr0Kv.net
>>708
レスが遅くなりましてすいません。
xの定義にx自身を参照していますが、それだけでは
再帰的に定義されているとは言えないということですか。
例えば次の関数 f は再帰的に定義していると皆が言います。
f n = if n == 0 then 1 else n * f (n-1)
これと >>706 の x とは何が違うのでしょうか。
737:デフォルトの名無しさん
21/02/08 07:06:31.27 aZaTrcsy.net
>>728
fix x はxの定義じゃなくてfixの定義では
738:デフォルトの名無しさん
21/02/08 09:04:48.35 THE6D9/g.net
>>729
fix定義の中でlet節を使って定義されているxの話です。
739:デフォルトの名無しさん
21/02/08 12:31:08.86 hFpKnaPX.net
>>717
リスト使ったメモ化の理解にはいいんですけど、その例も実は遅いんですよね。!!がO(n)なので。
module Main where
import Data.Function
import qualified Data.Vector as V
main = do
let memo = fibMyMemo 50000
print $memo 50000
print $fibMemo 50000
fibMyMemo l = fib
where
fib = ((V.map f $ V.enumFromN 0 (l + 1)) V.!)
f 0 = 0 :: Integer
f 1 = 1
f n = fib (n -1) + fib (n -2)
memoize f = (map f [0 ..] !!)
fib f 0 = 0
fib f 1 = 1
fib f n = f (n - 1) + f (n - 2)
fibMemo = fix (memoize . fib)
740:デフォルトの名無しさん
21/02/08 18:33:31.66 USGkiU7i.net
>>728
マジョリティとマイノリティの違いとか、合法とグレーの違いのようなものだと思えばいいだろ
再帰的な関数と再帰的な型はよく知られている
一方、関数でも型でもないケースは未知のウイルスのようなもので
既存のものと同じだとすぐ決めつけるのは判断が早過ぎる極論
741:デフォルトの名無しさん
21/02/08 20:09:46.17 xtdfQPSv.net
>>731
そうですね。
なので、実際は Trie 木でメモする MemoTrie が効率良いと思います。
742:デフォルトの名無しさん
21/02/09 17:58:55.95 czfvLw+x2
アスペルガー症候群と高機能自閉症
「反復運動」と「限定された物事へのこだわり・興味」
3つの診断基準
①人とのやり取り、関わりが難しい(社会性の障害)
②コミュニケーションがとりにくい(コミュニケーションの障害)
③興味・行動の偏り、こだわり(限定的な行動・興味・反復行動)
ASD(自閉スペクトラム症、アスペルガー症候群)の症状
細部にとらわれてしまい、最後まで物事を遂行することが出来ない
視線があいにくく、表情が乏しい
切り替えが苦手、決まったパターンと違うと癇癪を起こす、集団での活動・遊びが苦手。
743:デフォルトの名無しさん
21/02/10 06:55:43.73 w+SbAYAx.net
>>732
すいません、結局のところ、どういう事でしょう?
744:デフォルトの名無しさん
21/02/10 10:35:38.44 tXb64EJq.net
法律や善悪の判断の正しさを疑うのと同じレベルの懐疑的な思考が
数学やデバッグにも必要ということかな
745:デフォルトの名無しさん
21/02/10 11:17:11.88 tXb64EJq.net
静的型は最強とかガベコレは最強とかいう考えが
疑われるようになったのは半分ぐらいHaskellが原因だよね
746:デフォルトの名無しさん
21/02/10 13:30:33.82 em7GM66H.net
>>732←こいつまだいたのか
気持ち悪すぎる
747:デフォルトの名無しさん
21/02/10 14:18:45.17 tXb64EJq.net
ここは無料だしこんなもんだろ
良いものはみんな課金される
748:デフォルトの名無しさん
21/02/11 14:43:11.06 /UgD5Hp7.net
地獄の沙汰も金次第
だが天国への言及はない
749:デフォルトの名無しさん
21/02/11 16:56:32.70 zBw+qxbZ.net
ねえ、購入厨
ひょっとしてHaskellは、きみが同じ地獄を繰り返す毎に
強力なフリーソフトになっていったんじゃないのかい
750:デフォルトの名無しさん
21/02/13 21:17:16.21 kqsb0S1y.net
悪役キャラには著作権等のコンプライアンスを意識させると邪気が抜けてしまう
豆知識
751:デフォルトの名無しさん
21/02/14 18:40:01.75 .net
なぜ Haskell スレはワードサラダ bot に狙われてしまうのか
752:デフォルトの名無しさん
21/02/14 20:59:33.34 2j5v2BhK.net
>>743
ネットの差別発言を排除する努力すらやらない人がいるから
ワードサラダとやらを排除する努力なんて誰もやらないのは当たり前だぞ
こんな簡単なことがなぜ理解できないんだ
753:デフォルトの名無しさん
21/02/14 21:27:29.30 A1oxlP1a.net
731はワードサラダなレスうぜぇなぁくらいの意味しかなくワードサラダなレスが存在してしまう理由を実際に疑問に思っているわけではないという簡単なことが何故わからないのか
754:デフォルトの名無しさん
21/02/14 21:49:22.17 2j5v2BhK.net
731は、うぜぇなぁ以外何も考えてなかったというのか
それは差別意識しかない絶対悪じゃないか
755:デフォルトの名無しさん
21/02/15 01:08:13.78 Qrz9kKC+.net
もっと危機感を持ったほうがいいよ
母国語の特徴までネチネチいじられたら外国語はこわくて使えないだろう
英語ができないとプログラミングもできない
756:デフォルトの名無しさん
21/02/15 17:23:26.09 Mv5LolEs.net
なんかこのスレ会話が噛み合わないよな
>>744←こいつとか明らかに頭おかしいし
こういう人外化け物がうじゃうじゃいるから「特技はコミュニケーション能力です」みたいなゴミ文系が社会で調子に乗り始めるんだろうな
757:デフォルトの名無しさん
21/02/15 18:24:29.13 Qrz9kKC+.net
コミュ力の悪用を止める方法で一番使えそうなのは制限時間を無くすことだ
5秒で答えさせるような問題でも時間のルールを無視してしまえば
そのゴミ文系ってやつの能力を擬似的にコピーできる
758:デフォルトの名無しさん
21/02/15 19:02:15.47 3zpQr6lX.net
Haskellの話は?
759:デフォルトの名無しさん
21/02/15 20:58:35.44 Qrz9kKC+.net
最小不動点を定義する半順序の定義がない
それと「再帰」の定義がない
760:デフォルトの名無しさん
21/02/16 10:45:42.61 AZNZAZhP.net
>>750
こういう話?
URLリンク(i.imgur.com)
761:デフォルトの名無しさん
21/02/16 12:56:19.11 VICwQMLs.net
質問なんですが,
URLリンク(levelup.gitconnected.com)
の一番上のコード内23-25行目の
iMinusOne <- cdRecursiveTD (i-1) stArr
iMinusTwo <- cdRecursiveTD (i-2) stArr
writeArray stArr i ( (i-1) * ( iMinusOne + iMinusTwo ) )
の部分を添え字使って
for j = 1 to 2
xs !! j <- cdRecursiveTD (i-j) stArr
writeArray stArr i ( (i-1) * ( sum xs ) )
みたいに書く方法ってありませんかね?
762:デフォルトの名無しさん
21/02/16 15:13:16.20 VICwQMLs.net
すみません自己解決しました
一応結果貼っておきます
cdRecursiveTD i stArr = do
____v <- readArray stArr i
____when (v == -1) $ do
______xsm <- newSTRef []
______forM_ [1,2] $ \j -> do
________x <- cdRecursiveTD (i-j) stArr
________modifySTRef xsm (x:)
______xs <- readSTRef xsm
______writeArray stArr i ( (i-1) * ( sum xs ) )
____readArray stArr i
763:デフォルトの名無しさん
21/02/16 15:27:24.80 twhDC3NA.net
xs <- mapM (\j -> cdRecursiveTD (i - j) stArr) [1 .. 2]
writeArray stArr i ((i - 1) * sum xs)
これでよくないですかー?
764:デフォルトの名無しさん
21/02/16 15:32:43.34 VICwQMLs.net
>>755
そっちの方が遥に良いですね…
ありがとうございます
765:デフォルトの名無しさん
21/02/17 14:02:08.57 YPZ4jTJ4.net
map f [1,1,1,2]のように重複の多いリストがあったら
fの実装を変える勢力とリストの構造を変える勢力の争いをどうやって解決できるか気になる
766:デフォルトの名無しさん
21/02/17 16:20:43.74 mAFPwKeZ.net
一回Set型にしてからListに戻す
767:デフォルトの名無しさん
21/02/17 16:22:11.25 mAFPwKeZ.net
もちろんリストの要素の個数減って良い場合の話だけど
768:デフォルトの名無しさん
21/02/17 22:40:59.85 0SJ3Yct4.net
>>757
具体的な問題状況(例)が示されなければ、次のような何にでも当てはまる
至極当たり前のつまらない回答しかできないと思うが。
目的、開発リソース(時間や設備、資料、費用など)、
開発者の能力やモチベーション、メンテの容易さなどを、
優先順位を考慮したうえで出来るだけ客観的に評価し決定する。
争うということは、優先順位や評価基準が定まっていないということなので、
まずはそれらを話し合って、あるいは上の立場の者がバシッと決める。
769:デフォルトの名無しさん
21/02/18 09:29:03.36 8Wc99cSo.net
なんかしょうもない話なんですけどウチの環境で次が通ります
test x = case x of
_ | odd x -> 1
oyherwise -> 0
main = do
print $ test 123
print $ test 456
なんか笑ってしまいました
770:デフォルトの名無しさん
21/02/18 09:31:00.46 8Wc99cSo.net
あ、イヤ違う
勘違いでした
すいません
771:デフォルトの名無しさん
21/02/18 10:58:11.75 jy6gqPJ4.net
>>760
客観的な目的というのは難しすぎて誰にも分からない
例えば個人的な借金を減らすことと国の借金を減らすことはどちらが客観的目的か
そうではなく、目的は主観で決めてOKというなら
それは結構面白い答えであって、つまらない答えではない
772:デフォルトの名無しさん
21/02/18 11:50:05.23 6bd12mxo.net
>>763
言葉が足りず、誤解させたようで申し訳ない。
客観的に行うのは、目的を定めることではなくて、
今やろうとしている事が定めた目的に合っているのか評価すること。
fの実装を変えることが目的に合っているのか、
それともリスト構造を変える方がより合っているのか。
目的というのは様々あるよね。
見聞きした新しい技術をラフに評価するための
トイプログラムを作ることが目的だったり、
次のリリースでメモリ使用量を10%削減することだったり。
客観的に評価することを意識しないと、気分や雰囲気に流されて、
メモリ使用量を抑える目標が、いつの間にか処理速度向上にすり替わってたりする。
また、目標は評価する一項目にすぎない。
リリース時期を守る方が優先順位が高い状況もある。
だから、もろもろ含めて客観的に評価する。
逆にそうじゃないと、fとリストどちらを変えるのかなんて、決めようがないと思う。
773:名無しさん
21/02/18 15:29:22.47 jy6gqPJ4.net
>>764
気分や雰囲気に流されまくるまで想定しておくのが良い作戦だよ
流されないように対策するので想定する必要はないみたいな理屈は危ない
774:デフォルトの名無しさん
21/02/25 20:48:36.35 zWeVIvWn.net
ある対象がモノイドかどうかを問う質問です。
2つのリストのうち要素の少ない方のリストをそのまま返す、
同じ要素数ならば左側のリストをそのまま返す関数 f :: [a] -> [a] -> [a] があるとします。
ここで、ある型aのリスト全体の集合[a]と、その上の二項演算fとの組([a], f)はモノイドを成すでしょうか。
私は次のように、これはモノイドではないと考えます。
このモノイド性を考えるとき、その単位元の候補として、
もし集合に無限リストを含めないのならば最大要素数のリストを、
無限リストを含めるのであれば無限リストを取ります。
他に考えようがありません。
しかし、どちらにしても単位元の一意性が証明できません。
xs、ys 共に最大要素数のリスト、あるいは無限リストであり、かつ xs /= ys を満たすものは(型aによっては)いくらでもあります。
よって、([a], f) はモノイドではないと考えますが、これは正しいでしょうか。
モノイドの定義に照らし合わせるのではなく、
モノイドならば証明できるであろう定理が証明できないことに因っているのが、
なんとも気持ち悪いのですが・・・
そもそもモノイド性を問うには ([a], f) の定義が曖昧なのでしょうか。
775:デフォルトの名無しさん
21/02/25 21:30:50.20 hQOL6Vl7.net
モノイドではないに一票
776:デフォルトの名無しさん
21/02/26 01:35:18.34 7R2bTCy0.net
リストには同じ要素が何個も入ってもいいんだから単位元になり得るのは無限リストだけでしょ
ある無限リストを単位元eとするしかなさそう
ここでもう1つ無限リストaを用意してf a eしたらa返さずに要素の個数比較する時点で⊥になるからモノイドにならないと思う
777:デフォルトの名無しさん
21/02/26 02:07:21.86 Drny41hT.net
型は集合ではない
値は元ではない
プログラム上の関数は数学的な意味での関数ではない
Haskellは数学ではない
778:デフォルトの名無しさん
21/02/26 10:03:43.32 W2dsUZYE.net
モノイドでも集合論でも、公理が多過ぎて公理が偽になるなら
公理を減らせばいいじゃん