関数型プログラミング言語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/09/15(火) 00:17:11.21ID:wUKRYY2O
>>514
まだ自分でハッキリ確かめたわけじゃないんですけど
Applicative と Monoidal は同型なんだそうです

https://qiita.com/Guvalif/items/7f893d9a078e03c9e425

まだこっちはどういう意味で“同型”になるのかわかってませんけど
数学的な意味でのMonadは英語のwikiに詳しく説明が載ってて↓
https://en.m.wikipedia.org/wiki/Monad_(category_theory)
このFormal DefinitionがまさにHaskellのモナド則に繋がっていくのは確かめました
問題はApplicativeは圏論のどの概念に該当するのかの説明がサッパリ見つからないんです
2020/09/15(火) 02:19:25.61ID:PObv6BQ8
(a -> b) -> (m a -> m b)
m (a -> b) -> (m a -> m b)
(a -> m b) -> (m a -> m b)
こいつらは中央の->と左右の->を区別してないから数学的な意味が見えない

returnとjoinは->が一つしかないから問題ないが
2020/09/15(火) 10:15:51.98ID:TeSbfrM9
>>516
そう、Haskellの圏論がらみの話はその“冪対象”(exponential object)が絡むのがややこしい
しかしFunctorは当然としてMonadも冪対象を用いないで形式化されてる(というより計算論の世界への応用のずっと以前からある)
Applicative(=Monoid?)はどやねんという話なんです
圏論の世界ではなかったものが計算論の世界に導入されてから考え出されたもんなんですかねぇ?
2020/09/16(水) 01:31:29.62ID:yuR5T5xB
strong lax monoical functor
2020/09/16(水) 22:12:52.40ID:CfmtxJKj
モノイド圏とかモノイド対象とかあんのだけど、モノイド(モノイダル)関手ってのもあんのね

読む気は無いんだけど、アプリカティブ関手とモノイダルXXが同型ってのは無いと思うが
っておもったけど、関手同士なんだから、いくつか条件つければモナドとモノイドみたいな関係もありうるんかな?

あとは、カン拡張、随伴、普遍性(極限だっけ?) どれかから相互に変換出来るだっけ?みたいなもん?

どちらにしろ、定義の話で面白みは無いとは思うのだが
2020/09/17(木) 10:32:26.07ID:2a8IoKJu
見つけた

https://qiita.com/Guvalif/items/7f893d9a078e03c9e425

このサイトの人がまとめたpdfに書いてある
とは言ってもやはりclosed categoryは仮定してる
やっぱりapplicativeはmonadと違って“内部ホム”を持たない圏では定義できないんだろな
“内部ホム”もつ圏でmonoidal functorに<*>を定義するのはわりと簡単だけど↓
F(X) × F(Y^X)
→F(X×Y^X) (coherence)
→F(Y) (F(eval))
https://en.m.wikipedia.org/wiki/Monoidal_functor
pureが全然できんなぁと思ってたら“strong”という条件からpureが作れるんだな
まぁHaskellて圏の話するときはHASKて言えればいいんだからコレでわかったことにしよ
521デフォルトの名無しさん
垢版 |
2020/09/28(月) 01:41:48.03ID:0EuZ+v5t
[Promise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)
の小さい例題の[html](https://pastebin.com/yxSRyg2u)をアップした。
async/awaitはPromiseのお助け文法になっているが、それは扱っていない。実行環境は、
[RStudio](https://rstudio.com/products/rstudio/)から
[Node.js](https://nodejs.org/ja/)を呼び出している。
2020/10/14(水) 04:31:41.26ID:+VLXbnA3
>>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)
523デフォルトの名無しさん
垢版 |
2020/10/31(土) 09:11:59.11ID:UJYxitvT
http://walk.northcol.org/haskell/adts/
>代数的データ型(algebraic data type)とは,図のように木構造で表現される値からなるデータ型のことです.

必ず木構造に限定されるんだろうか?
OOPではオブジェクトグラフがありネットワークになりうるが、
Haskellでは絶対に木と考えて良いの?
2020/10/31(土) 12:29:50.75ID:cEs7BAmA
いいんじゃない?
型の全体は文脈自由文法で規定されるクラスだから木になる希ガス
525デフォルトの名無しさん
垢版 |
2020/10/31(土) 12:34:33.57ID:fxcwqRC2
この木なんの木きのこる木
2020/10/31(土) 12:37:07.03ID:CAmth+XY
見たこともない木ですから
独自実装のバグが出るでしょう
2020/10/31(土) 13:17:41.17ID:cEs7BAmA
でもよくよく考えたら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
528デフォルトの名無しさん
垢版 |
2020/10/31(土) 13:26:01.44ID:UJYxitvT
再帰的なデータ型はグラフにできるのでは?
2020/10/31(土) 13:37:30.03ID:B0ELcd4k
最終的に暴走しないで展開が停止するものだけをデータ型と呼ぶならそうだけど、iterate (+4) 5 ですら無限の木になってしまう
2020/10/31(土) 21:13:27.13ID:3k5Im+3l
haskellの配列は代数的データ型でばないのか?
2020/10/31(土) 22:07:18.29ID:XiPKdEPZ
foldrなどの引数のことを代数的と言っていたような気がする
引数は(:)と[]でもいいし
(+)と0でもいい

引数を渡すと関数 [a] -> b が返ってくるが
これは関数というよりOOPの継承関係のような印象
2020/10/31(土) 22:34:53.43ID:B0ELcd4k
Haskell のデータ型は再帰を許すからな
どうしても「終端記号(大文字から始まるData constructet) を木構造に並べたもの」という説明をしたいなら無限グラフを使わざるをえない
533デフォルトの名無しさん
垢版 |
2020/11/01(日) 07:14:51.56ID:fIYIMdhR
http://walk.northcol.org/haskell/lists/#_%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AE%E7%95%B3%E8%BE%BC%E3%81%BF

1)foldr (+) 0 [1, 2, 3]
(+)とカッコがつく理由は?

2)map' f = foldr (\x a -> f x : a) []
xは[]の各要素?aは何?
2020/11/01(日) 08:58:44.92ID:Srz4hpJo
1)
http://walk.northcol.org/haskell/operators/#_%E4%B8%AD%E7%BD%AE%E3%81%A8%E5%89%8D%E7%BD%AE%E3%81%AE%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88

2)
このままだと対応する値が存在しないので、少し書き換える
map' f xs = foldr (\x a -> f x : a) [] xs
xはxsの各要素、aは最後の要素では[]で、
それ以前は後ろの要素に(\x a -> f x : a)を適用した結果
2020/11/01(日) 09:15:58.91ID:v6ASK7zT
>>533
>
> 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) ]

となる
2020/11/01(日) 10:14:49.54ID:1eMkmBeN
因数?引数ではなく?
Haskell用語なのかな
2020/11/01(日) 10:21:30.53ID:Srz4hpJo
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]
2020/11/01(日) 10:25:40.23ID:Srz4hpJo
おっと、具体例の「foldr (\x a -> f x : a) [1,2,3]」は
「foldr (\x a -> f x : a) [] [1,2,3]」の誤り
2020/11/01(日) 10:36:13.55ID:B/d//mYI
い・・・引数
2020/11/01(日) 10:54:46.55ID:z/eHKN3/
引数です
orz
普段“因数”の方が使う人なのでうっかりしたorz
2020/11/01(日) 11:03:53.67ID:93fSMn/e
こ・・・因数
2020/11/01(日) 11:05:28.12ID:z/eHKN3/
こ?
2020/11/01(日) 11:11:25.51ID:4+fLUvoM
だ…因数
2020/11/01(日) 12:57:34.37ID:9/8GaKcH
ひきすう
2020/11/01(日) 15:22:11.82ID:N8AW169o
引数を「ひきすう」と読むのは、同音異義語との混同を避けるための慣用読みだと思ってた
化学(ばけがく)、鼻腔(びくう)みたいな
546デフォルトの名無しさん
垢版 |
2020/11/01(日) 15:24:45.41ID:BdB3gM+x
返り血
2020/11/01(日) 17:34:03.38ID:S9fsJ+JS
Parameterとargumentsの違いがよくわからない
2020/11/01(日) 17:44:50.76ID:5aO2zs3I
https://qiita.com/yuba/items/141bdb2df407ee37417f

だってよ
2020/11/01(日) 17:59:46.68ID:S9fsJ+JS
よくわからんし一緒ってことか
2020/11/02(月) 00:43:34.64ID:TnMF05Pn
質問です
このサイトでNum instanceをDerivingする話が出てました

https://qiita.com/HirotoShioi/items/8a6107434337b30ce457

実際このページの次のコードはうちの環境でも通ります
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)
2020/11/02(月) 00:43:43.72ID:TnMF05Pn
---- エラーメッセージ
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)
| ^^^
2020/11/02(月) 21:44:04.17ID:aBc5dqas
こうすりゃ無理やり通すことはできるけど、
そもそもパーサ同士の足し算等々でどう動いて欲しいのか分からんから
まともなインスタンス宣言が書けん

{-# 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
2020/11/02(月) 23:56:16.57ID:Zq9JUsOb
>>552
元は別スレに出てた問題で
「与えられた文字列の中で“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入れる方法見つからなくてなんとかならんもんかと
2020/11/03(火) 01:59:40.73ID:WdkpFDBO
わざわざNumのインスタンスにしなくても、これでいいのでは
makeP = fmap sum . mapM ( fmap length . manyTill anyChar . char )
2020/11/03(火) 10:26:04.44ID:qaG2IpUi
>>554
うん、まぁ別に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 (...) の (...) にかけるやつとダメなやつの基準がわからない
実用本位でよく使うやつだけ用意されてるに過ぎないのかな?
2020/11/03(火) 11:32:34.46ID:WdkpFDBO
一応、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
2020/11/03(火) 11:50:57.17ID:hn8kPJNe
>>556
なるほど、文法的に通っても意味的に文法には出てこない"Num rule"が補償されないからダメって事なのかな?
まぁ今はclassのメンバ関数の自分が利用するやつだけ定義する必要無くなったみたいだから手で書いてもいいんだけど、>>550の例だと

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 とかだと惨劇になってしまう
2020/11/03(火) 18:12:46.66ID:oSP8TPsC
この話の面白いところは
Parser Intという型を宣言する言語と
そもそも型を宣言しない言語
どっちが生産性高いかってことだよ
559!id:ignore
垢版 |
2020/11/06(金) 20:16:57.19ID:uZSEyxFl
stackくんさぁ、コンパイラのダウンロードが200MB強あるんだから、低速回線は途中で切断されるとかよくありそうなことじゃん
サスペンド・レジューム機能搭載は必須じゃないのかね
きょうびyoutube-dlでさえ向こうに切断Forbiddenされても今までダウンロードした分は残ってて、再度ダウンロードを開始した際には途中から残りの部分をダウンロードすように始まるってのにさ
仮に205.86 MiB / 205.87 MiBまで来て切断された場合
リトライすると0 MiB / 205.87 MiB からだなんてお互い不幸になると思わないのか?
こっちは成功するまで永遠に繰り返すんだぞ? むしろそっちの方がそちらにとっても迷惑じゃん
それとも低速回線は死ねっていう差別的思想を持っているのかね?
2020/11/08(日) 11:31:57.94ID:Bx8aZf2L
一方TeXはisoイメージを使った
2020/11/08(日) 13:05:47.79
パターンガードの変数の束縛は局所的なのですが、全ての場合で共通して使用してほしい束縛はどうやりますか?
2020/11/09(月) 01:15:49.21ID:4MQyK7K1
>>561
質問の意味がよく分からないのだが、コード例を出せる?
こんな風に書けたらいいのに、みたいな。
2020/11/09(月) 19:55:38.03
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 = ...

みたいな書き方の時にもやりたいんです
2020/11/09(月) 19:58:42.43
おっと無用な改行が一々入っちゃった。。。
2020/11/09(月) 20:20:48.18ID:UhW/CkjO
>>563-564
where で出来なかったっけ?だめだったかな?
2020/11/09(月) 21:00:20.89
あ、できました。
お騒がせしました(////)
2020/11/11(水) 19:20:13.76ID:qheOKxfd
正格評価について質問です

ひとつの引数しかない関数 f を正格評価するときには

f $! x

でよいようですが2引数の場合はどうするんですか?

( f $! x ) $! y

で x, y を先に展開してくれますか?
良さげなんですがどう確かめたものやら
なんか正格評価と遅延評価で格段に計算量が変わる f の例ってありますか?
2020/11/11(水) 21:38:04.29ID:TR1bVb0l
遅延評価がなくてもGCはメモリ解放を遅らせている
GCをいじるにはIOが必要

$!を使うのにも少なくともモナドが必要と考えるのが自然なのでは?
x' <- return $! x
y' <- return $! y
return $! (f x' y')
2020/11/11(水) 22:07:05.86ID:F87BSTFR
>>568
そうなんですか?
とりあえずモナドで試してみます
兎にも角にも正格評価と遅延評価でこんなに計算の回数が違ってくるってのなんかご存知ないですか?
例えば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'

で比べると目に見えて計算量が違うみたいな奴で「正格評価が効いてる」って目に見えてわかるような例があるとありがたいんですが
570デフォルトの名無しさん
垢版 |
2020/11/12(木) 14:57:12.09ID:+Y5HOlnE
正格評価と遅延評価で計算量が変わるといえばtaraiじゃね?
2020/11/12(木) 23:16:18.57ID:G64JuFLE
⊥になるものでいいじゃん
2020/11/13(金) 06:27:56.29ID:ewlhvLCU
trace や unsafePerformIO で評価順を調べられないかな
2020/11/13(金) 12:04:46.50ID:oAmrFI5R
みなさん情報ありがとうございます
今んとこヒマな時にやってみた実現は

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
まだタライとかは試して見てません
取り急ぎご報告まで
2020/11/16(月) 23:33:39.07ID:bCg5e61i
>>567
もうとっくに解決したかもしれませんが、評価の順は 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 の順に出力されます。
2020/11/18(水) 01:05:30.21ID:VzwFaHaO
>>574
イヤ、まだ奮闘中です
おぉ、そんな便利なものが
使ってみます
576デフォルトの名無しさん
垢版 |
2020/11/21(土) 23:31:14.57ID:ak7brOTq
Haskellはライブラリの中身を覗くと
Template Haskellを駆使した
グッチャグチャの実質別言語みたいなコードがザラなのがなぁ・・・
水面下の白鳥状態じゃねーか
2020/11/22(日) 16:59:26.57ID:gt3QNmmg
ゴミライブラリ使うのやめて良いやつ作って公開してくれ
2020/11/22(日) 17:19:45.03ID:MRtbpg3I
在学中か学校出たての経験浅い奴しか担い手がいないのだろうからそんなもんなんだろう

純粋関数型言語は学生がかかるはしかみたいなもので
やがて計算機科学の現状に絶望し去ってゆく
現在のコンピューターは手続き型に最適化されているのだ
2020/11/22(日) 18:37:00.71ID:36XuvgN2
単純に関数型言語がわかる人が少なすぎるからじゃないの?
2020/11/22(日) 20:14:41.06
居飛車党と振り飛車党の闘いは続く
2020/11/23(月) 02:58:53.25ID:v8DPq2Nr
イヤ、まぁ純粋に速度とか効率とか考えたら手続き型言語の方が優位なのはその通りでしょ?
だって現在の計算機がノイマン型の手続き型の処理をするために設計されてるんだから
そりゃバリバリにチューニングしたら手続き型言語には絶対勝てない
その時代時代の最新の計算機の性能をフル活用しないとできないような処理は当面関数型言語の出番は回ってこない
しかしそこまでの処理でないならやはり関数型言語の活躍できる場面も出てはくるだろうけど、しかし例えそうなったとしても手続き型言語も関数型言語も両方臨機応変に使いこなせるようになるとなると中々難しいから、結局どちらか選ぶなら手続き型言語という事になってしまう
しばらくは関数型言語が実務の場面でバリバリ使われるようになるのは中々難しい
当面研究者とか、サンデープログラマーの趣味の世界でしか出番ないかもしれない
2020/11/23(月) 03:10:25.23ID:i6Fa5mHr
並列並行処理を型で表せる辺り、強力なんだけどなぁ
2020/11/23(月) 03:19:37.79ID:vzAx9TtB
Reditを見てると、Haskellerの求人も結構あるんだが
2020/11/23(月) 12:02:25.91ID:B9DSaA3p
居飛車と振り飛車というのは危機感が足りない
ガソリン車と電気自動車だ
個人の就職じゃなくて会社が丸ごと潰れるリスクを想定するための研究だよ
2020/11/23(月) 13:19:57.85ID:XIoHPhIo
一句できた!

『次に来る』
言われ続けて
数十年
(来ない)
2020/11/23(月) 13:27:42.48ID:izonrGpC
近未来
今となっては
古臭い
2020/11/23(月) 13:29:17.88ID:XIoHPhIo
>>586
いいね!
2020/11/23(月) 14:40:17.74ID:B9DSaA3p
新しいなんて嘘つくより古いものは古いものとして扱う歴史や古文の方が正しい
2020/11/23(月) 20:51:18.66
関数型言語を処理するために設計されたコンピュータってどんな構造なんだろ
2020/11/23(月) 21:33:53.00ID:B9DSaA3p
みんなが数学好きで自己啓発嫌いなのは処理速度じゃなくて
嘘をつかないかどうかの問題
2020/11/24(火) 01:11:11.02ID:wCic/rFb
>>589
LISPマシンというものがかつてありましたなあ
2020/11/24(火) 03:49:22.53ID:EBaS3Lgi
JAVAチップが実現されてればスタックマシンだからFORTH最強だったのでは
2020/11/24(火) 21:00:48.17ID:BgPUrN9t
速度は実はそこまで重要じゃない
飛行機からメンテナンスハッチ取り除いて何kg軽量化しましたって言ったところで、仕事好き定量評価好きなにわかが、わかりやすい数字見て喜ぶだけで、実際はそんな嬉しい話じゃない
というかそもそももっと遅いスクリプト言語は流行ってるし
2020/11/24(火) 21:12:41.51
Haskell でゲーム開発したいんですが
FRP は死滅しちゃったの?
2020/11/24(火) 21:44:37.33ID:2dUwtFIm
>>594
死滅の意味がよく分からんが、問題なく使える。
stackageにもあるでしょ。

それはそうと、なんで初めから難しいFRPを使おうとするの?
普通に素直に設計して作ってみればいいのに。
2020/11/30(月) 15:39:12.43ID:nSv/4rn0
bind演算子の名前の由来ってなに?
なにも束縛してなくね?
2020/11/30(月) 17:26:29.13ID:+w97lXkL
a >>= b
がdo記法で
do
x <- a
b x
みたいになるからじゃね?
2020/11/30(月) 21:06:13.38ID:qo5X+4ip
(>>) これも bind と言うよ
599デフォルトの名無しさん
垢版 |
2020/12/02(水) 00:25:53.39ID:E6FeESB6
ここで聞いていいのかわからないけど…
Nixのいいチュートリアルとかってある?
2020/12/04(金) 21:16:59.61ID:kdWDDBYk
これとかどう?

https://github.com/Gabriel439/haskell-nix
601デフォルトの名無しさん
垢版 |
2020/12/05(土) 12:39:37.62ID:Na39OKS5
ブログ書いてたら彼女と無料で海外留学という名のデートに行けた話【影響力やばい】
https://www.youtube.com/watch?v=Y8Q1z3Mi7BQ
若いうちから人を雇ったり、任せるクセをつけるべき理由とは?
https://www.youtube.com/watch?v=6yAvDQxhldI
【対談】インフルエンサーマーケティングに300万円突っ込んでみた結果...
https://www.youtube.com/watch?v=AMjWD0F8PLQ
収入を上げたければ、自分の影分身を作るべし
https://www.youtube.com/watch?v=V3Kc-lUxH88
勉強のために10日間で21個のアプリを作った話【初心者時のプログラミング学習】
https://www.youtube.com/watch?v=JkN5kmR9dgk
学校では教えてくれないことの中にはお宝が眠っている
https://www.youtube.com/watch?v=oq92u9nJ7FY
ブロガーからステップアップしていくために必要なスキル
https://www.youtube.com/watch?v=F6qsOyRIaQE
602デフォルトの名無しさん
垢版 |
2020/12/05(土) 23:01:31.80ID:gIoCKCst
>>600
すごい良さげ。ありがとう
2020/12/05(土) 23:45:36.72ID:gZAhFzLL
>>601
すごい良さげ。ありがとう
2020/12/06(日) 02:18:39.34ID:HA18eG30
>>601
グロ
605デフォルトの名無しさん
垢版 |
2020/12/08(火) 09:15:41.98ID:VKXi32Vk
実際にちょっとしたプログラム書いてみると
メモリ周りの最適化が困難なんだよなこの言語。

しかも最適化の方向性がアルゴリズムの改良ではなく
言語特有のボトルネックの回避がメインになるから
コードを見ても最適化の意図が分かりにくくて
一見無駄に冗長に記述してるだけに見えるコードが出来上がる。
2020/12/08(火) 11:08:46.52ID:EAPrHNYX
最適化の意図なんてPythonと同じでいい
ライブラリは全部Cで書いてmainだけHaskellで書け
2020/12/08(火) 12:02:52.73ID:mZ7rlOd+
一時期あんなにモナドの記事とか書かれまくったのに、最近盛り上がりに欠ける
Haskell製アプリも企業が採用したって話もほとんど聞かないけど、気のせい?
尖ったところで使われてるんかな
2020/12/08(火) 13:07:23.14ID:EAPrHNYX
言語関係なく企業が作ったアプリを買ったことがほとんどない
個人が書いた本を買うことはある
2020/12/08(火) 13:30:45.48ID:xvXTXIvz
まぁなんだかんだHaskellは実用性というより、やはり数学研究の一貫の色合いが強いからなぁ
2020/12/08(火) 13:52:48.29ID:CqCSsxMG
一環では?
数学の前に国語の研究をしたほうがよいのでは?
2020/12/08(火) 15:02:11.16ID:xvXTXIvz
お前はまず自分の人間性を見直せ
煽りじゃなくマジで
2020/12/09(水) 01:52:25.38ID:6n7tUtuW
Haskell自体は面白くて本や記事も読むけど、なんか書く気起きないんだよな
でも他の言語で関数型由来の機能が追加されたときに「あ、これHaskellでやったところだ!」ってなれる
613デフォルトの名無しさん
垢版 |
2020/12/17(木) 17:53:27.84ID:9eI2x+Uu
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)
614デフォルトの名無しさん
垢版 |
2020/12/17(木) 17:53:45.49ID:9eI2x+Uu
モナド無しだけど、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);
}
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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