関数型プログラミング言語Haskell Part21
Haskell初心者ですが、RealWorldHaskell読んでいて、状態モナドもどきを自作してみようと思って newtype State s a = StateMonad { stateFunc :: s -> (a,s) } とやってみて somefunc :: (a -> b) -> State s a -> State s b somefunc f (StateMonad g) = StateMonad( \s-> (f(fst(g s)), snd(g s))) は通るのに instance Functor (State s) where fmap :: (a -> b) -> State s a -> State s b fmap f (StateMonad g) = StateMonad( \s-> (f(fst(g s)), snd(g s))) が通らないのがわからなくて困っています。 ★質問: fmap をどのように宣言するのが正解なのでしょうか? (fmap :: (a -> b) -> State s a -> State s b の一行を消しても型推論で通りますが、それは気持ち悪いのです)。
>>5 data Fix f =Fix (f (Fix f))
とすると、値コンストラクタFixは、ひとつの f (Fix f) 型の引数をとる
Fixはkindが (*->*)->*
fはkindが *ー>*
つまり、f自体が何かひとつの型引数をとるということ
fを[]とすれば
Fix::[Fix []] ー> Fix []
fをMaybeとすれば
Fix::Maybe (Fix Maybe) -> Fix Maybe
fを(,) a とすれば
Fix::(a, Fix ( (,) a ) ) -> Fix ( (,) a )
7 :
4 :2013/01/21(月) 19:10:00.99
教わって解決しましたマン Functorインスタンスはfmap の型宣言書いちゃいけないんですね
>>6 重ねてですまんが"f(Fix f)"の意味が分からんです・・・
Fix fの値を受け取るコンストラクタを持つfという型って意味でよい?
f (Fix f)は型引数としてFix fをとる型 [Fix f]とかMaybe (Fix f)とかIO (Fix f)
了解です。ありー ちょっと咀嚼してきまふ(´・ω・`)
新スレおめでとうございます^^
>>4 標準だと、instance宣言の中ではメソッドの型は宣言できない
書くまでもなく型は決まってるし
エラーメッセージでそのこと言及してくれよコンパイラ
haskellで書いたプラグインを動的に読み込む仕組みってないですか?
xmonad方式はどう?
>>16 言語処理系を作ってるので、ユーザー側で他の処理系(ghc)が必要っていうのは避けたいんですよね
ファイルをディレクトリに置いたら読み込めるっていうのが理想なんですが
やっぱりffiで共有ライブラリを読み込むしかないんですかね
function sum(a, b){ return a + b; } sum("こんにちは"); これをhaskellで書くとどうかけますか?
わけがわからないよ
>>18 sum' x y = x + y
main = let
hello = sum' "こんにちは"
in putStrLn "Hello"
コンパイルエラーになるけど
>>20 オブジェクト指向しかやってないからさっぱりわからないです
関数型ってむずかしいですね
わけがわからないよ…
サム「こんにちは」
プログラミングhaskell読んでるけど7章あたりで頭が追いつかなくなってきたわ。。。
dataのあたりで今詰まってる。ShapeとかCircleで説明してるやつ。 オブジェクト指向とちょうど逆になってるのかな。 何が逆かはうまく説明できないけど、なんかそんな感覚。
オブジェクト指向って何やってんの そうまで他の言語を難しく考えることもないと思うんだけど
オブジェクト指向的にインタフェースと多態で書くと、 ・データの種類(クラス)の追加は簡単 ・処理(メソッド)の追加は面倒 代数的データ型で書くと、 ・データの種類(構築子)の追加は面倒 ・処理(パターンマッチする関数)の追加は簡単
データの種類で最も重要なのは ・null ・null以外 の二種類 nullという種類の追加が面倒という性質は 静的型付けの存在理由に関わる重要な性質だ
オブジェクト指向的な多態とnullは関係ないだろ Haskellにだって、nullよりある意味厄介な⊥というのがあるし
lazyは厄介だ 実行時よりもコンパイル時という考え方に反する
bottomを厄介者扱いとかバチあたりな
リストをたくさん結合すると非効率というのがいまいちわからない 実際どういう状況で非効率になるの?
たくさんが問題じゃなくて ++ が問題。 後半のリストは共有できるにしても、前半のリストは複製しなきゃなんない。
>>29 オブジェクト脳の俺にもう少し(もうだいぶ)詳しく教えてくれないか ?
ちなみに上の人とは別でこのすれ初かきこです
>>34 配列ならスペースを多めに取ってnullを入れておく状況とか
仕様を正確に知っている人でも、必要なスペースは予測できない
仕様書には知っていることだけ書けばいいが
コードには予測できないことまで書かないと上手く動かない
関係ないが、講議で、ソフトウェア科学における最悪の発明が「NULL」という話を聞いた
発明した人と批判した人の両方が賞をもらえるという話をどこかで聞いたような気がする
>>38 UNKNOWN先生がアップを始めたようです
最高の発明だよ
NULLはビリオンダラーミステイク by Tony Hoare
言語を選んだ時点で失敗が確定するというのは 時期尚早な最適化の話と内容が180度違うから困る
'こんにちはundefined' 許すまじundefined
⊥が現れるのは再帰がある場所に限定される が評価されるタイミングは限定されない
いちおうMaybeモナドすげEEEEEEってのはわかったつもりなんだけどさ モナド使うとなんでIOの副作用が分離されるの ? IOってところに環境のいろんなところが入っているから それをひきずり回しているからIOじゃないところは純粋であるって説明 どっかで読んだんだけど、具体的にはどうやってるの ? おしえてキボンヌ
47 :
デフォルトの名無しさん :2013/02/06(水) 21:34:07.28
指定したN番目の値を返す関数を作りたいのですが、上手く出来ません。 例えば、nthElementIs [1,2,3,4] 3 > 3見たいにしたいです。 isTrue :: Int -> Bool isTrue number | number > 0= False | otherwise= True nthElementIs :: [a] -> Int -> a nthElementIs list number = case (list) of [] -> case (number) of 0 -> [] otherwise -> error"okh" (x:[]) -> case (number) of 1 -> x otherwise -> error"z" (x:xs) -> case (number) of isTrue -> error"df" otherwise -> nthElementIs xs (number - 1)
>>46 どうやってという疑問は比較的簡単で
Stateモナドで状態を引きずり回しているのと同じように
RealWorldを引きずり回しているのが IO
無限リストなの?
>>47 よーしパパそれほどHaskellerじゃないけど調子に乗って習作書いちゃうぞー
nthElementIs :: [a] -> Int -> a
nthElementIs (x:xs) num | num == 1 = x
. | num > 1 = nthElementIs xs (num - 1)
これじゃいかんの ?
不適なデータが来ても何とかするなら
nthElementIs :: [a] -> Int -> Maybe a
nthElementIs [] _ = Nothing
nthElementIs (x:xs) num | num < 1 = Nothing
. | num == 1 = Just x
. | num > 1 = nthElementIs xs (num - 1)
とか
51 :
デフォルトの名無しさん :2013/02/06(水) 22:20:12.67
>>50 ありがとうございます。
コードがすっきり分かり易いです。
エラー書くよりはMaybe使った方がやはりいいのでしょうか?
後、ガードとcaseの使い分けはあるのでしょうか?
聞いてばっかですいません。
>>50 はものすごく教科書的でいいね。
nthElementIs xs num = last . take num $ xs
俺ならこの質問されたらめんどくさいから一行でこう書くわ
駄目な大人になってしまった
nthElementIs xs n = xs!!(n-1)
明らかに学習目的なのに既存の関数を使って正解って… あとインデックスは0から開始するように習慣づけるべきだと誰も指摘しないことに驚いた
>>46 分離したというけど、無関係ではないよね
IOの中では関数を適用できるが、関数の中ではIOを実行できない、という関係
コールバック関数を自分でコールできないみたいな状況に似ている
既存の関数使わないでどう答えろと (==)も(<)も(>)も(!!)も、全部既存の関数だぞ
monadだから分離されているというべきなのか。 IOの型修飾を外すには、(>>=)するしか無いから分離されているというか、、、
59 :
50 :2013/02/06(水) 23:51:46.77
>>51 > エラー書くよりはMaybe使った方がやはりいいのでしょうか?
> 後、ガードとcaseの使い分けはあるのでしょうか?
すまん。自分も習いはじめでよくわからんとです。
>>52 教科書読んだばかりですから !!
一流のHaskellerになると関数合成ばしばし使うのですね。
自分、関数合成にまだ発想が行きません。
便乗質問ですが、ピリオドとダラーの使い分けなんですけど、
nthElementIs xs num = last . take num $ xs
も
nthElementIs xs num = last $ take num $ xs
も
nthElementIs xs num = last $ take num xs
も結果は同じなのですがどう使い分けてます ?
本来なら(引数の順番さ000え逆だったら、nthElementIs num xsだったら)
nthElementIs num = last . take num
って書きたかったのでしょうけど
>>55 > あとインデックスは0から開始するように習慣づけるべきだと誰も指摘しないことに驚いた
そうしなければいけない何らかの事情があるのかと思ってた
((!!)を使うといけないのもエラー処理のためとか今後の拡張とかの理由かと思ってた)
>>57 「既存の(ほぼ答えそのものの)関数を使って…」って書いたら満足だったか?
ていうか、よく見たら思った以上に酷い回答ばっかだった
まず、「is」が付く名前は慣習的にBoolを返すものだから、「nthElement」か単に「nth」とすべき。
>>52 はありえない
>>50 は
(nthElement [] n) がNothingを返すのはいいが、
(nthElement [1,2,3,4] -1) などは明らかにプログラミングエラーなのだからエラーにするべき。
(他の言語なら最後の要素を返すのも考えられるが)
そうしないと潜在的なバグがコードに紛れ込み、かえって品質を落とすことになる。
入門書の最初の方に出てくるような例なんだから、これくらいまともに回答してくれよ
人に文句言ってばかりで自分では何もしないカスがいるみたいだから、 俺が代わりにPreludeに載ってる!!の例から丸写ししてやる。 nthElement :: [a] -> Int -> a nthElement xs n | n < 1 = error "nthElement: negative index" nthElement [] _ = error "nthElement: index too large" nthElement (x:_) 1 = x nthElement (_:xs) n = nthElement xs (n - 1)
丸写しして気づいたけど、2chでの回答としては
>>53 が一番の正解で間違いないね
ほぼ答えそのものの関数があるならそれを示せばいいだけだ。わざわざ転記する必要ねーじゃん
病院池
>実際にいちばんまともなコメントをしているのは自分だと思う
実際に一番まともなコメントは
>>63 以外にないと思うぞ。マジで。
名前は突っ込まれたから変えたけど正直問題の本質と関係ないからどうでもいいし
>インデックスをわざわざ1から開始にするのは意味がわからない
問題読み直したら?
>それなら答えは(!!)を使えということだろ。
だからそれが
>>63 で既出だって話。ぐだぐだ書いてる俺らより余程簡潔にまとめてるし、
ソースのリンクなんか貼らなくてもPreludeのソースなんてド素人でも見つけられる。
安価ミス。
>>63 じゃなくて
>>53 ね
×実際に一番まともなコメントは
>>63 以外にないと思うぞ。
○実際に一番まともなコメントは
>>53 以外にないと思うぞ。
×だからそれが
>>63 で既出だって話。ぐだぐだ書いてる俺らより余程簡潔にまとめてるし、
○だからそれが
>>53 で既出だって話。ぐだぐだ書いてる俺らより余程簡潔にまとめてるし、
>>62 あなたがそれを一番の正解と判断するに至った価値基準は?
それはあなた以外の人も持っていて当然のもの?
それ以外の価値基準が存在しうることは理解してる?
なんかここ怖い
基地外隔離スレだから仕方ない
>>65 ,66
なんでそんなに切れてるわけ?
>>47 を見れば初学者なのは一目瞭然なんだから、インデックスは0から始めるものだと教えてやるのは当然だし、
どう考えても争うような本質的な問題じゃないだろ?
> ソースのリンクなんか貼らなくてもPreludeのソースなんてド素人でも見つけられる。
リンクを貼るの難しそうだしね。無理言って悪かったよ。
Haskell怖いです(震え声)
Haskellは怖くないよ
>>47 とかたぶんFizzBuzz並に簡単な問題
それさえもできない人が何故か回答してるからおかしくなってるだけで
nth elementの取り出しなんて、preludeのソース詠めばいいだろ
入門書読んだ後は、!!とか自作して遊んでたな。。。(遠い目)
プログラミングhaskell 8章まで来たけど、いよいよ全く意味がわからなくなって挫折しそうボスケテ!
8章は載ってるコードじゃ動かないし、その後の章の知識が必要だから初見で理解するのはたぶん無理だろう 理解できると一番面白い章だけど、最初は適当に読み流した方がいい
8章から難易度がスコーンと上がるからな すごいHの方に浮気するのもアリだと思う
個人的にはすごいHaskellの方が難しいと思う とくに序盤は
RWHで挫折してまたRWHに戻ってくるまでが勉強です
81 :
デフォルトの名無しさん :2013/02/08(金) 13:22:59.19
dammy
>>77 8章はPreludeのdo,returnとかが邪魔してコード通り動かないよなw
とりあえずdo表記を使わず、Preludeにある関数は名前を変えて
なんとか練習問題まで終わらせたけど・・・。
9章の電卓も期待した動きと違う。主に遅延評価のせいだと思うけど。
入力した式が評価されるまでputStrの実行も遅延させられるみたいで、
電卓のテンキー(飾り)が表示されない・・・。
俺は練習問題に関してはここで心が折れたw
本文は、10章まで読んだけど、11章からは応用問題みたいだから
後でいいやと読むのを止めたw
Haskellの最初の挫折ポイントはモナド 次の挫折ポイントが値の直接変更はSTモナド内で引きこもってやるということ 次の挫折ポイントがモナド変換
モナドって、"最初の"挫折ポイントか? 私は、まだモナド山に入山してさえいない。その前でちょっと挫折気味。 今、プログラミングHaskell 13章を読んでいる最中。 すごいHaskellはアダプティブファンクターのところで止まっている。 プログラミングHaskell を読み終わったら、すごいHaskellのアダプティブファンクター 〜モナドのところに進んでみる。
adaptive functor!
>アダプティブファンクター 挫折した感がものすごく良く伝わってくる
挫折ポイントはいっぱいある。 型クラス、型構築子、データ構築子などの独特な型の世界が 行く手を阻んでいる。 ついでに型でエラーが出まくって慣れないと 何のエラーかよくわからんのがなぁ。
走り出してからエラーになるくらいならコンパイル通らない方が正義
俺も正義だと思うが、それとエラーメッセージが分かりづらいのは別の話
コンパイラがプログラマの意図を読めない限り ありのままに起こった事を言うしかない 何を言ってるか分からないと思うが
それとエラーメッセージが分かりづらいのは別の話
Haskell(GHC)で最も意味不明のエラー in 俺 * is a rigid type variable bound by 〜
93 :
デフォルトの名無しさん :2013/02/11(月) 10:59:30.81
data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving (Eq, Show) fromDayToNum :: Day -> Int fromDayToNum day = case (day) of Mon-> 0 Tue -> 1 Wed -> 2 Thu -> 3 Fri -> 4 Sat -> 5 Sun -> 6 fromNumToDay :: Int -> Day fromNumToDay number = case (number) of 0 -> Mon 1 -> Tue 2 -> Wed 3 -> Thu 4 -> Fri 5 -> Sat 6 -> Sun isWorkDay :: Day -> Bool isWorkDay day | (fromDayToNum day >= 0 && fromDayToNum day <= 4) = True | otherwise = False isWorkDay' :: Day -> Bool isWorkDay' day = case (day) of (fromDayToNum day >= 0 && fromDayToNum day <= 4)-> True _-> False 何故、isWorkDay' はfromDayToNumを使えないのでしょうか?
>>93 case 中の -> の左側はパターンしか書けない
関数適用はパターンではないので、そういう使い方はできない
パターンは例をたくさん見ると理解がはやいと思う
直感的には構造で分岐する
例を見るもなにも、パターンマッチには基本的にコンストラクタしか使えないってだけじゃないの? 一応例外的にリストは[]が使えるけど
基本的にリテラルも使える
[]が例外的? 意味ワカンネ
基本的にn+kは消えた
束縛した変数を使えるという思い込みがたまに発生してデバッグに時間がかかる
>>97 空リストじゃなくて[]を使ったパターンのことね
[a, b]みたいなパターンも使えるけど、これはコンストラクタじゃないでしょ?
Haskellはあくまで静的型付けなんだという事が コンパイル時のストレスと 実行時のパフォーマンスをもたらす
> ((:) a ((:) b [])) -> b ( ´;゚;ё;゚;) ←これに見えた
104 :
デフォルトの名無しさん :2013/02/11(月) 20:05:23.50
なるほど、つまり関数適用はガードで。 それ以外はcaseで良いと? riverse :: String -> String riverse list = case (list) of [] -> [] (x:xs) -> riverse xs ++ [x] xRiverse :: String -> String -> Bool xRiverse list rlist = case (list) of [] -> if (rlist == []) then True else False (x:xs) -> if (list == (riverse rlist)) then True else False では何故xRiverseの(list == (riverse rlist))は使えるのでしょうか?
なぜも糞もねーだろ もう一回入門書読み直してこい
>>104 if e1 then e2 else e3
という形のとき e1 はBool の式なら何でもいい
list == (riverse rlist) は Bool の式なので使える
式っていうのは、どんどん計算することができて、途中に関数適用があったら実際に適応して計算を継続していく
そして、どんどん計算した結果、(Boolの式なので)TrueかFalseになる
もしTrueならif全体が e2 に、Falseなら e3 になる
ポインタ同値性を判定する方法ってなんかない?
ポインタアナリシス
109 :
デフォルトの名無しさん :2013/02/11(月) 20:54:35.49
>>105 ~106
丁寧な説明ありがとうございます。
今ちょうど入門書を読んでいる所だったので。
ありがとうございました。
>>107 おまえが入門者なら、答えは「ない」
そうでないなら、ポインタ同値性で何をやりたいかによる
111 :
デフォルトの名無しさん :2013/02/12(火) 06:56:54.59
引数を1つ取って、引数の型シノニムを文字列として返す関数ってどういう風にやればいいの?
>引数の型シノニム って何? 引数の型を文字列として返したいなら、 import Data.Typeable typeName :: (Typeable a) => a -> String typeName = show . typeOf
>>112 引数の型を返して欲しいけど、型に別名つけたときに別名が返って欲しいという意味で型シノニムと言ってみた。
型が返るだけでも十分だ。ありがとう。
JavaやC#のインターフェースはクラスにある約束事(メソッドなど)の実装を強いることにより、その約束事を前提にロジックを書くことができると思いますが、 同時に、その約束事を実装しているものであれば実行時にそのロジックにどんなオブジェクトでも渡せるという仕組みでもあると思います。例えばUIの何らかのコントロールが渡されてきてDrawメソッドが呼ばれるような。 Haskellの型クラスはある約束事を想定するという意味では似ていると思いますが、コンパイル時に呼ばれるものが解決されて実行時にその約束事を守るどんなものでも渡せるというものではないですよね? Haskellの場合は上にあげたような何らかのコントロールを渡して何らかの処理をするような処理というのはどんなふうに書くもんでしょうか?
何言ってるんだかわからん
>>114 例えば (>>) :: Monad m => m a -> m b -> m b。
これは、Monad 型クラスのインスタンス型であれば
どのような型の値でも被演算子になれる(引数として適用できる)のだが、
このようなものでは不満か?
ただ、この場合は m a 型引数 と m b 型引数は
Monad 型クラスの同じインスタンス型でなければならないがな。
f :: (Monad m, Monad n) => m a -> n b -> m a
とかなら Monad 型クラスの違うインスタンス型の値が引数になれる。
> Haskellの場合は上にあげたような何らかのコントロールを渡して何らかの処理をするような処理というのはどんなふうに書くもんでしょうか?
何らかの型クラスのインスタンス型の値を渡したり、関数を渡したり、
関数内でパースされ解釈・計算される何らかの値(計算式を表したツリーとか)を渡す、など。
プログラミングHaskellなんとか読み終わった。 「本物のプログラマはHaskellを使う」の3章〜4章あたりを読んでいる最中。 モナドはまだ‥わけわからんが、とりあえず式を追うことまでは可になった。
Haskell本って突然"->"とか説明もなく記号が出てくるの何とかならないのかって思う 初めて読んだとき->って何だよって本投げたわ
説明は必要になるまで遅延されます
121 :
デフォルトの名無しさん :2013/02/13(水) 07:14:39.41
質問です。 reverseList :: [a] -> [a] reverseList list = case (list) of []-> [] (x:xs)-> reverseList xs ++ [x] isPalindrome :: (Eq a) => [a] -> Bool isPalindrome list | (list == (reverseList list))= True | otherwise= False のisPalindromeは(Eq a)=>を入れないと(==)のテストが出来ないことが分かりました。しかし、 isSum :: [a] -> Int isSum [] = 0 isSum (x:xs) = 1 + isSum xs は (Num a) =>が無しでも動きます。 どう言う時に"()=>"を使用すればいいのしょうか?また、全ての関数にこの"()=>"を付けた方がよりいいのでしょうか?
>>117 その2.2-2.3辺りの事ですね。
んーとこれはコンパイラのスイッチでこういう書き方を許容出来る様に出来るけどデフォルトでは出来ないってことですかね。デフォルトではその辺どうするんでしょう?
ray tracerの例で言ってるようなrendableであるヘテロジニアスなリストとして扱って、時にはその中でballのものだけごにょごにょするような。
通常は代数的データ型でやるんでしょうが、例えばUIフレームワークみたいなものを作るとしたらどうしても後からフレームワーク外で後から定義されたものも同じ様に扱うニーズが有るので代数的データ型は使えないだろうと。
>>116 自分が言いたかったのは
>>117 に有る様なヘテロジニアスなリストを元にdynamic dispatchするにはとなると思います。
書き方が足らなくてすいませんでした。
型は良い事をするための物ではなく、悪い事を防ぐための免疫だよ 悪いやつが出てきてないのに何かしようとするのはアレルギーと同じ アレルギーをなおすには型を弱くすればいいよ
>>121 isSum 内の + は 型 a に関して足してるわけじゃないので (Num a) => という a に関する制約は不要
a にかかわらず要素の数を足している
コンパイルエラーになった時のように、必要なときに必要なだけ書けばいいと思うよ
125 :
デフォルトの名無しさん :2013/02/13(水) 13:37:37.02
ありがとうございます。 きっちり型が制限されてないときだけ()=>を使います。 けど、どう言うときに「型がきっちり制限されている」のか分かるのでしょうか?[a]がElemとかShowとかが必要な時? 持ってる本(introduction to functional programming language using haskell)では良く分からなかったので。
単相性制限ってまだ生きてる?
windowsにhaskellをインストールしたら1GBも容量食った 何でこんなにでかいの?でかすぎやしないか?
>>127 > 何でこんなにでかいの?
サブフォルダ一つ一つの容量を調べてみれば、
何が容量を食っているのか分かるだろ。
その「何が」が分かれば、「どうしてか」も
今よりはもっと良く推測できるだろ。
何故そんな簡単な努力を怠って質問してくる?
129 :
デフォルトの名無しさん :2013/02/13(水) 20:13:01.85
それは簡単な努力じゃないだろ
プロHaskeller様にとっては簡単なんだろ
普通にエクスプローラーを開いてフォルダのプロパティを見れば良いだけだが もちろん、フォルダのサイズを一覧できる Haskell プログラムを書いても良いが、 そこまでしなくても分かるだろ
なんで食い下がるんだよw さしたる瑕疵のない質問に対して恫喝的な態度を取ったのを非難されてるんだろ
>>128 ハア?そんなの調べてどうすんの?アホなの?
では、簡単な努力もしない教えて君には、
どのような態度をとれば良かったんだ?
俺は努力して調べろと言った。
調べる方法も示した。
これ以上の適切なレスはそうそう無いだろう。
>>133 調べれば、「何でこんなにでかいの?」という質問に対する答えを、
「自分で」より推測しやすくなる。
>>134 だからさ、それを調べたところで何になるの?
>>135 疑問を自分で解消するための糸口が得られる。
いいぞもっとやれ
>>136 だからサイズが大きいファイルなどを調べてどうすんの?
開発者にもっと軽量してくださいってお願いするの?
さっきから的外れな話してんじゃねえよ
>>139 >>127 が質問しているのはインストールしたHaskellの容量が1GBもある「理由」。
何に容量を食われているのか分かれば、そこから理由が推測できる。
(でかすぎやしないか?というのは、もっと小さくできないのかという思いを
疑問系で発言しただけのことだろうから無視)
もし
>>127 が単なる愚痴であるなら、そもそも、そんなものはチラ裏にでも書いておけ
これから数スレ以内に "アスペ" が含まれる確率80%
イイからとっととファイルの階層を容量やフォルダ名、フォルダの中身をZipper的に辿れるもんサクッと作れや( ´Д`)y━・~~
なんでこんなにでかいの? ↓ フォルダ見てみればいいじゃん ↓ はあ?なんでそんなことしなきゃいけないんだよ
>>144 悪意を感じるな。
意図的に省略したか?
なんでこんなにでかいの?
↓
フォルダのサイズを見れば「何が」でかいのか分かる
「何が」が分かれば「どうしてか」は今よりもより良く推測できる
↓
はあ?なんでそんなことしなきゃいけないんだよ
だろうが。
単に、なんででかいんだよ、と言うだけで思考停止してるんじゃなくて、
自分でできるところまでまず調べろ。
容量をでかくしている主犯を調べるのはそのとっかかりだ。
その主犯がHaskellにどう関係してくるのか、
そいつは何故そんなにもでかいのか、
容量をでかくしているのはそいつだけなのか、これらを考えるのはその後だ。
>>125 とりあえず、
isSum ['a', 'b', 'c']
が
3になるのはよろしいでしょうか ?
mySum [] = 0
mySum (x:xs) = x + mySum xs
の場合(Num a) => aという制約が必要になります。
なぜなら、+の部分を型で書くと a + Intとなります。
aがNumのインスタンス?でなければならないので
Num a => aという制約が必要になります。
isNumの場合そのようなものはなく+の両辺の型は
1 (<= Numのインスタンス?) + Intであり、aに関する制約はまったく必要ないので
制約に関する記述は必要なくなります。
これでいいのかな?
添削して
インスタンスって表現でいいんだっけ ?
>>146 0 :: Num a => a
(+) :: Num a => a -> a -> a
やな
Intに限らない
最近血痰と喘息の気があるな アスペルギルスかな
149 :
デフォルトの名無しさん :2013/02/14(木) 10:58:17.65
>>146 つまり、
>>121 のisPalindromeは相等性を持つ型(値が明確)と認識されなかったからダメだった。
だから、その式ではa==aがInt == Int、Bool == Bool、String==String なのか解らないが為に()=>の制約が必要?
制約って関数の型をもっと強めることも出きるような物って感じがします。
型変数a, b, ...は制約ではなく写像って感じ 型変数に具体的な型を入れると何かが出てくる 入れる際に制約がもしあれば型クラスを指定する
151 :
146 :2013/02/15(金) 00:48:04.33
>>149 ところでHaskellってList同士の比較も素でできるのすごいなぁ
で、
(==) [] lst = lst == []
(==) (x:xs) (y:ys) = (x == y) && (xs == ys)
だとして
x == yの部分が(Eq a) => a -> a -> Boolであるので
xの型は(Eq a) => aである必要があります。
IntもBoolもStringもEqのインスタンスなのですが、例えば
add1 x = x + 1
のadd1の型は(Num a => a -> a)(aをとりaを返す*関数*)となり
Eqのインスタンスではなく(==)の引数にすることができません。
(add1 == add1はエラーになる)
isPalindromeで(==)を使っている以上aはEqのインスタンスである
必要がある以上、引数がEqのインスタンスであることを要求する意味で
(Eqのインスタンスでない型の引数を拒絶する意味で)
Eq a => a
の制約が必要となります。
こんな感じ ?
素ではできんよ。==を使いたかったら[a]型の型変数aはEq型クラスのインスタンスである必要がある。
遅レスだけど
>>100 それは単なるシンタックスシュガーだろ
a:b:[]と同じなんだから実質コンストラクタ:を使ってる
Haskellで用いられるモナドと、ライプニッツが主張したモナド、 何か関係ありますか?
ありません。次どうぞ
同じ名前なのは偶然ですか? 根底の概念の部分で共通性があるとか、とういう事も無いのですか?
黙れ
QtでGUIが構築できるようになるパッケージって無いですか
>>160 いや、言われて当然だろう。
ライプニッツがモナドを提唱していた事を知っていたのなら、
「モナド ライプニッツ haskell」でググれば、
それぞれのモナドが無関係なことは直ぐ分かる。
それもしないで食い下がってくれば言いたくもなるぞ。
最近、簡単な調査を怠ってくだらない質問してくる奴多いな。
haskellスレは今日も殺伐
Foldableはあるのに Filterableってクラスはないのかしら
標準ライブラリには無いね。 Filterableクラスは、具体的にはどんな関数を持ったクラス? どのようなケースで必要になる? あるいは、どのようなケースであると便利?
[a]にもSet aにも同名で同機能なfilterという関数が定義されてるのに まとめられてないのが気持ち悪く感じたので 同じような機能なら何でもかんでもまとめてクラスにしちゃおうって考え方はマズイかなあ
foldは単位元と二項演算が必要というのが制約だけど、filterは大した制約ないでしょ?
いや普通にあってもおかしくないけどfilterable 何がそんなに気に障るのか
大した制約があるかどうかが重要であるという説明をしないと 大した制約があるかどうかに着目した理由がわからない
collctionならnatualにfilterableだわねえ
リストの方のfilterは集合と違って、順序が保存される点で厳密には同じ機能でないからとか
>>166 Data.List と Data.Set には、filter の他にも
partition や split、(\\) など、共通な関数はあるが、
これらはどうする?
Data.Array 系や Data.Map 系などと Data.Set の間にもいくつかあるね。
>>171 同じ型のコレクションになるんだから当たり前かと。
instance Filterable (Hoge a) eliciting Foldable なんて機能があればいいな(提案)
もう目が覚めました 今日からhaskellやめてpython使いになります
>>176 まあちょっと座って落ち着きなさい
このお茶を飲みなさいな
OPyH(オパーイエッチ)
Haskellって、最も目を覚ましていないと使えない言語だと思う
そういう自画自賛的なのは要らないから
眠い頭じゃコードが書けないってことだろ
ハッスル!ハッスル!
別に追い出すなんて言ってないんだから…… べべ別にアンタが居なくなったら寂しいとかそういうんじゃないんだからねっ!
やはりRubyにおけるRails的なものが無いと広まらない と思ったけどYesodがそういう位置づけだったか 「Yesodだとこんな簡単にWebアプリが作れる!!」的なステマが足りないのだろうか
売り込むなら簡単よりも堅牢とかじゃない? 正直Rails等を置き換えるほどのものじゃないと思うけど
「Yesodだとこんな堅牢にWebアプリが作れる!!」 だと、それが本当だとしても、インパクトが少ない。 目を輝かせたニュービーが大量流入するぐらいのキャッチーさが欲しいところ。
10分のコーディングでスゲーサイト作るところをYouTubeにアップするとか
そういうのはもう溢れてるだろ……
Haskellで作ったシステムで金融危機予知してぼろ儲けしたはwwwww みたいな事するしかないな
>>189 イージーカムイジリーオカダというではないか
そもそもHaskellの取っ付きにくさを見ればキャッチーなんて縁遠くて然るべきなのだ
Haskellの標語には質実剛健こそ相応しい
こういう奴がいる限りは流行んないでしょ
僕が間違ってました
全力で成功を回避する
197 :
デフォルトの名無しさん :2013/02/19(火) 15:35:29.87
入門書の最初の方で必ずと言っていいほど、素数を求めるとかの数学的な例題を出すのがいけないと思う そのせいで他言語やってきた普通の人が他の言語で解決してきた問題をhaskell(関数型言語)でどう解決するのかがぴんとこなくなっていると思う
入門書自体そんなにないけど最初に素数を求める本なんて具体的にあったっけ?
200 :
デフォルトの名無しさん :2013/02/19(火) 17:21:42.63
>>197 そう言う意味では「ふつける」はいい本だったと思う
何故か一部で評判が悪いけど
Haskell十分流行ってんじゃん Smalltalkと比べろ
RealWorldHaskellみたいな本が増えるといいんですけどね Natural Language Processing for the Working Programmer(Web上で無料で読めるからググれ) はNLPを題材にしてHaskellも同時に学ぶという本で、 良さそうだったんだけど、まだ未完成。あと英語だし。
その本のタイトルちょっと慣用とずれてるよね。 応用を視野に入れて理論をスッキリと概説するのが〜 for working 〜シリーズなので。 タイトルに反してHaskellコードベッタリな本になってしまってる。
204 :
デフォルトの名無しさん :2013/02/19(火) 17:36:32.47
Effective Haskellみたいな本はないの?
RWH以外のなにかを求めている?
RWHは内容的にも物理的にも重い そしてちょっと古い
・HaskellのTips本が無い ・設計上の陥りやすい罠とその回避策をまとめた本が無い ・Haskellデザインパターンが無い ・Haskellメタプログラミング(HMP)本が無い ・HaskellのガベコレがJavaに適わない ・『Haskellの設計と進化』本が無い ・Haskellマガジンが創刊されない ・Haskellラムダキーホルダーが無い
Haskellラムダキーホルダーって、それただの棒だよね
Haskellラムダお菓子として展開すればあるいは
なにより、マスコットが居ない
ラムダ饅頭
そうだ!必要なのはマスコットだ!
よし、マスコットは病弱そうな女の子風でどうだ?
Haskellの国際大会で日本の女子中学生が初めて金を取った ってニュースをNHKが流せば、かなり人気出ると思う
必要ないだろ…
マス子ちゃん、君の堅牢な部分をみせてごらん?
レシピブックほしい
Set aとかMap k aってどうあがいてもFunctorとかのインスタンスに出来ないの? 出来るような仕様にしても良くね?不便じゃね?
>>216 ガッチガチじゃあないか……
どれ、早速……
ん、もうかい?意外に速いんだな
>>218 Map型は標準ライブラリの中でも既にFunctorクラスのインスタンスだよ。
Set型は標準ライブラリの中ではFunctorクラスのインスタンスではないが、
必要なら自分でインスタンス化すれば良いだけじゃないか?
遠隔操作事件のウィルスがHaskellで作られてたなら警察も操作やりやすかっただろうに( ´Д`)y━・~~
Setはまともな形でFunctorにするのは無理だね
>>222 では逆に訊くが、もし Set 型が Functor クラスのインスタンスだったら、
Set a 型の値 x と関数 f::(a -> b) に対する関数適用 fmap f x は
どのような戻り値になって欲しいんだ?
具体的な値を使って例示&説明してみてくれ。
その値と戻り値の組みが作れるかどうか = Functor クラスのインスタンスにできるかどうか
という事で良いんだよな?
>>223 まともって何だ?
今自分がプログラムするのに必要となる型に対して、
必要な分だけ過不足無くインスタンスを定義すれば良いだけだと思うが。
もしかして、fmap の結果が同じ値になってしまって、
Set の構造が元のものと変わってしまう、と言いたいのか?
でも、それは仕方ないだろ。
今自分がプログラムするのにそのような仕様が欲しいのなら、
そのようにプログラムすればいい。
構造が変わってしまっては困るのなら、
構造が変わらない場合だけを正しく定義し、
構造が変わる場合はエラーを出すように作れば良い。
>>225 instance Functor Set where
fmap = Set.map
とすれば型エラーになるはず
↓こんな風に
http://codepad.org/ynVAbAoF fmapは(a->b)->Set a->Set bの関数を要求するけど、これにaとbがOrdであることを付け足すことが文法上無理って話じゃないの?
>>226 そりゃ fmap = Set.map なんてすればエラーになるに決まってる。
fmap = 自作しろ
という話だ。
正確に言えば、自分のプログラムの仕様に合うように自作しろ、ということだ。
あと、Set 型は instance (Ord a) => Set a ではない。
Monoid クラスのインスタンスであるために
型引数 a が Ord クラスのインスタンスであることが要求されるが、
Set 型自体が Ord クラスのインスタンスになっているわけではない。
まぁたしかに、Set 型を使う関数の多くが、
型引数が Ord クラスのインスタンスであることを要求してはいるがね。
ちょっと何言ってるかわからないですね… Set a のaがOrdを想定していることはMonoidと何の関係もないし、aがOrdでないようなSet aはemptyとsingleton以外には基本的に構築できないし、当然すべきでもない 型チェックをパスするfmapを定義することは、自明で無意味なもの(fmap _ _ = empty とか)を除いて不可能
>>229 もとの質問をちゃんと読んでくれ。
>>218 どうあがいても無理なのか? と彼は訊いているんだよ。
Haskell の仕様としてできない事になっている、と勘違いしている。
(Map も Functor ではないと勘違いしているのだから、思い込みも甚だしい)
これを否定する事実を提示するだけで、この疑問は解消されるだろう。
つまり、あがけばできるし、できない仕様にはなっていない事を示せば良い。
instance Functor Set where
fmap f s = let xs = toList s
xs' = fmap f xs
in fromDistinctAscList xs'
それに元の質問は、Functor 版 Set をどのようなシーンでどう使いたいのか
まったく言っていない。
だから、質問は無理かどうかを訊いているだけなのだろう。
fmap = undefined でなんでもFunctorだよ!
せめてFunctor則を満たせ
mapMonotonicは単に型が通るだけで、fmapとしては全く無意味な定義だよ
もし質問の回答として
「fmap _ _ = empty にすればいいよ」
と言われたら、質問者を馬鹿にしてるととられて当然だ
そしてfmap=mapMonotonic も全く同じレベルの話だ
だいたいMonoidのインスタンスであるためにOrdがどうこう、みたいな全く頓珍漢なデタラメを言いながら、
>>218 を「思いこみも甚だしい」だなんてよく言えたものだ
彼は単にMapがFunctorであることを知らなかっただけだろう
>>233 > 彼は単にMapがFunctorであることを知らなかっただけだろう
質問する前に、標準ライブラリのドキュメントの Data.Map のページを見て、
Functor のインスタンスではないかどうかを確認するのが
「普通の質問者のすること」だと思うが。
仕様上できないと思っており、確認もしないのなら、
知らないというよりは思い込みだろ(知らないの部類に入ることかも知れんが)。
質問する前にちょっと確認するだけで分かることだぞ。
正確に言えば、ドキュメントの Data.Map のページには、
This module re-exports the value lazy Lazy API, plus several value strict functions from Strict.
と書かれているのだから、Data.Map.Lazy や Data.Map.Strict を見て確認するだろ。
そこにはちゃんと Functor (Map k) と書かれている。
>>234 たかだかその程度の瑕疵じゃないか
MonoidのためにOrdがどうこうみたいな意味不明な妄言を書いたり、全く無意味な定義で「インスタンスにできる」と言い張ったりするのは「普通の解答者のすること」じゃないよ
少なくとも彼を叩けた立場じゃない
>>235 あぁ、ごめん
Set 型自体が Ord クラスのインスタンスになっているわけではない、
というのは俺の勘違いだ。
Ord のインスタンスになっている。
たしかに叩けた立場じゃないな。
それは謝る。
申し訳なかった
>>218 >>235 それとは別に、
>>218 の、「どうあがいても」無理か、という疑問には
俺は問題なく答えてるよな。
できない仕様になっている、という誤った認識をちゃんと正してるつもりだが。
>>235 あと、「インスタンスにできる」として例示したものが
全く無意味な定義かどうかは、質問の内容によるだろ。
こういうシーンでこう使いたいのだができないか、
と具体的に質問されれば、あの例では全く無意味である可能性は高い。
しかし、あの質問の内容ならば、無理では無いこと、
できない仕様では無いことの証拠を示す例で十分だ。
それを、こちらが勝手に質問の意図を推測するのは余計だと思うぞ。
いやどうあがいてもまともなFunctorインスタンス無理だろ ここでいう「まともな」とは ・Functor則を満たす ・ドキュメントで明示的に禁止されているやりかたでSetのAPIを使わない の二点を守ること
fmap=mapMonotonic でもFunctor則は一応満たすよ まあFunctor則を満たす「だけ」だけど
>>230 ってFunctor則満たすんじゃね
ぱっとみ反例が思いつかん
満たすよ Functor則はね でもFunctor則しか満たさない
Functor則に従うなら問題ないな
ドキュメントで明示的に禁止されているやりかたでSetのAPIを使わない
ってのがよう分からん
SetのAPIで使い方にルールがある関数があって、
そのルールを満たさないと普通はコンパイルエラーかなんか出るけど、
>>230 みたいなことをすると、エラーにならないからダメってことかな
なんか変なやつが住み着いてるな
245 :
218 :2013/02/20(水) 23:34:10.28
fmap は Set.map と同じ仕様を望んでたけど 無理っぽいですね
>>243 ほとんどの関数において、なぜSet aのaがOrd aであることを要求されているかわかる?
>>243 たとえばfromDistinctAscListには、昇順なリストしか渡しちゃだめって書いてあるよね
>>230 だとfromDistinctAscListに昇順でないリストが渡るかもしれないからまともじゃない
前提がないなら、
>>218 の「どうあがいても」は
>>238 で言われるところの「まともな」範囲の話と考えるのが常識的だと思うの
>>247 でもさ、それを言ったら標準ライブラリ自体が「まともじゃない」ってならない?
標準ライブラリが、昇順なリストしか渡しちゃだめ、というルールを設けてるんだから、
昇順性を壊さない関数だけ fmap に渡せるというルールを設けてもいいじゃん。
なんでそれを使った自作関数がルールを設けたらまともじゃない扱いになるの?
>>249 自分で定義する関数ならルールは仕様の一部として勝手に決めていいけど、
クラスメソッドはクラス定義の段階で既に仕様が決まっているから、条件を付け加えるのはまずい
(実用上便利なら、仕様を厳密に守らないインスタンス(Numのabsが実装されてないとか)でも
それなりに許容されるけど、
>>230 はあまりにも壊れてる)
>>245 ちゃんとやるにはFunctorの定義に手を入れる必要がある
たとえば、
{-# LANGUAGE ConstraintKinds, TypeFamilies, KindSignatures #-}
import qualified Data.Set as S
import GHC.Exts (Constraint)
type family Domain (f :: * -> *) a :: Constraint
class Functor' f where
fmap' :: (Domain f a, Domain f b) => (a -> b) -> f a -> f b
type instance Domain S.Set a = Ord a
instance Functor' S.Set where
fmap' = S.map
type instance Domain [] a = ()
instance Functor' [] where
fmap' = map
諸君、久し振りに議論しているね
254 :
218 :2013/02/21(木) 08:24:29.44
『すごいH』にモナドとしての[]を拡張して確率値付きにしてやろうというのがあったけど
http://codepad.org/8KWk2kXP 結果が Prob {getProb = [(2,1 % 4),(3,1 % 2),(4,1 % 4)]} になるように
同じ事象をまとめたいのだけどそれには a がEqである必要あるから無理だよね?
255 :
デフォルトの名無しさん :2013/02/21(木) 16:20:40.14
[3,1,2,8] -> [1,2,3,8] , "abdc" -> "abcd"この様に小さい順に並びか得たいです。 remove :: (Ord a) => a -> [a] -> [a] remove _ []= [] remove k (x:xs) | k == x= remove k xs | otherwise= x : remove k xs maxElement :: (Ord a) => [a] -> a maxElement []= error"" maxElement [x]= x maxElement (x:y:xs) | x < y= maxElement (y:xs) | otherwise= maxElement (x:xs) inOrder :: (Ord a) => [a] -> [a] inOrder []= [] inOrder (x:xs)= maxElement (x:xs) : inOrder (remove (maxElement (x:xs)) xs) 綺麗にコードしたいのです。
ただのソートじゃないか
257 :
デフォルトの名無しさん :2013/02/21(木) 19:30:36.43
すいません。勉強の為に出来るだけprelude?の関数は使わないようにしたいのです。 Quicksortでしたっけコレ?
quicksort [] = [] quicksort x:xs = [y|y<-xs,y<=x] ++ x ++ [y|y<-xs,x<y]
間違えた quicksort x:xs = [y|y<-xs,y<=x] ++ [x] ++ [y|y<-xs,x<y]
Haskellでソートの実装を学ぶなら 題材はクイックソートよりもマージソードだろ
261 :
259 :2013/02/21(木) 20:10:12.44
恥の上塗り…… quicksort x:xs = quicksort [y|y<-xs,y<=x] ++ [x] ++ quicksort [y|y<-xs,x<y]
比較回数のオーダーがクイックソートじゃないよな
はあ?
>>261 みたいなのってxsを2回スキャンするの?
y<-xs,x<yの部分(なんて呼ぶのかわからんので教えてくれるとありがたい)は
firter hantei (x:xs) = if (hantei x)
then (x:(firter hantei xs))
else firter hantei xs
相当のことしてるの ?
quicksort (x:xs) = let sub [(as,bs)] (y:ys) = if y < x
then sub [((y:as), bs)] ys
else sub [(as, (y:bs)] ys
sub lst [] = lst
in
let (small, large) = sub [([], []) xs
in (quicksort small) ++ [x] ++ (quicksort large)
ってやったら効率よくなる ?
それとも無駄 ?
あと、
quicksort [] = []
は必要だよNE ?
265 :
デフォルトの名無しさん :2013/02/21(木) 22:34:38.03
>>263 クイックソートのアルゴリズムも知らんのか
>>264 君のコードが何を意図しているのか、正直よく分からんが・・・
>>261 のコードが xs を2回走査してるという認識は正しい。
同じ事は1回の走査で可能だ。
現に Data.List の patrition 関数は1回の走査でリストを二分している。
実際は quicksort [] = [] は必要だが、
>>261 はHaskellのクイックソートがどういった形になるのか、
外観を軽く示しただけだと思うから、
その文脈においては敢えて書く必要性は乏しいだろう。
>>265 「比較回数のオーダーがクイックソート」という言葉の意味が汲み取れない、
という意図の「はあ?」だと思う。
このコードがO(n×log(n))じゃないと思ってるということ?
>>267 「オーダーは O(nlogn)だ」というのは分かるが、
「オーダーがクイックソートだ」というのが分からない、ということかと。
ナンシー : The order is the quick sort.
ボブ : pardon?
>>261 がquicksortじゃないと思う人、素直に手を上げて!
要素の並び替えがin-placeじゃない(微妙なライン) pivot選択にmedian-of-medians使ってないので最悪計算量で死ぬ(無くてもいい)
空間計算量が最悪O(n^2)(やばい)
スルーされちゃったけど 254 は無理って事でいいよね?
うん
計算量をパパッと言える人カッコいい
lazyな処理系の空間計算量ってよほど慎重に考えないと間違えるよな。 それも、甘く見積もる方向に。
276 :
デフォルトの名無しさん :2013/02/22(金) 16:21:55.14
data Atree a = Null | Node (Atree a) a (Atree a) deriving (Show) minElement :: (Ord a) => Atree a -> a minElement (Node (Null) x (Null)) = x minElement (Node (lTree) y (rTree)) = Node (minElement lTree) y (rTree) 木の中で最小の値を出したいのですが、うまく出来ません。なんで?
277 :
デフォルトの名無しさん :2013/02/22(金) 16:24:57.45
すみません。自壊しました。 minElement :: (Ord a) => Atree a -> a minElement (Node (Null) x (Null)) = x minElement (Node (lTree) y (rTree)) = minElement lTree でした。
disintegration
279 :
デフォルトの名無しさん :2013/02/22(金) 18:47:26.22
自壊ー>自己解決でした。それはそうと、二分木の削除が出来ない。 data Atree a = Null | Node (Atree a) a (Atree a) deriving (Show) delete :: (Ord a) => a -> Atree a -> Atree a delete x Null= Null delete x (Node (lTree) y (rTree)) | x < y= Node (delete x lTree) y (rTree) | x == y= join lTree rTree | x > y= Node (lTree) y (delete x rTree) join :: (Ord a) => Atree a -> Atree a -> Atree a join lTree rTree | (isNull lTree) && (isNull rTree)= error"" | otherwise= Node (lTree) minimumElement (rTree) where minimumElement = minElement rTree isNull :: Atree a -> Bool isNull (Node (Null) x (Null))= True isNull (Node (lTree) x (rTree))= False minElement :: (Ord a) => Atree a -> a minElement (Node (Null) x (Null))= x minElement (Node (lTree) y (rTree))= minElement lTree 5 5 4 6 2 6 1 3 1 3 2 2<-こいつ消したいのですが.... 二分ヒープ?みたいなやつを実効したいのですが、もうこんがらがって訳わからない。
280 :
デフォルトの名無しさん :2013/02/22(金) 18:49:21.05
ごめんなさい。こんな感じです。 *Main> let c = (Node (Node (Node (Null) 1 (Null)) 4 (Node (Node (Null) 2 (Null)) 3 (Null))) 5 (Node (Null) 6 (Null))) *Main> delete 4 c Node (Node (Node Null 1 Null) 2 (Node (Node Null 2 Null) 3 Null)) 5 (Node Null 6 Null)
281 :
264 :2013/02/23(土) 08:13:36.61
>>266 ありがとう
自明なことかも知れないけど確認しておきたかったんだ
やっぱりmedian-of-mediansじゃないと(最悪でも)O(n)でmedian選択は無理ですよね?
マージソートでええやないの
ランダムに三つの値を選んでその中のmedianをpivotとする方法があるみたいですね。 median-of-3法というらしいです。 アルゴリズムイントロダクションに書いてありました。定数倍しか速くできないらしい。 ↑のアルゴリズムはこれの変種なのかな…。
えっ……
data d = d (IO d) これって再定義じゃないの? 参照透過性とかどうなってるの?
釣り針が太過ぎです。不合格
>>290 わからないニワカなら黙っててよ
既存のソース読んでて見つけたコードが
>>289 Haskellも副作用やってんじゃん
>>289 型構築子とデータ構築子は同じ名前が使えるんだよ
型と同名のインスタンスを作ってるって事ですか? C言語で言う class C{}; C* C = new C(); のような
イメージはそんな感じだけど違う data D=D' (IO D) こう書き直したとすると Dは型構築子D'はデータ構築子で役割が全然違う だから名前が被ったとしても問題がない Dは型だから関数の型宣言とかにしか使われない 例f::D->Integerみたいに D'はデータ構築子で、すなわち関数 D'::(IO D)->D 例 x::(IO D)->D x=\k->D' k
どうもありがとう Haskellに複数名前空間があることを知らなかった
既存のソース読む前にHaskellの入門書かなんかで勉強したほうがいい
型のことで便乗質問だけれど 型のレコード表記による定義をするとそのレコード名が 変数のアクセス関数として定義されるじゃん ? で、短い普遍的な名前にすると(例えば'name'、'length'等) 名前の衝突が起こるわけなんだけど やっぱある程度長い名前をつけなきゃだめなの ? オブジェクト脳だと短い名前付けたくなっちゃうんだけど Haskellでは名前の衝突はどう回避するの ? 長い長い名前を付けることに抵抗はないんだけど (どちらかというと説明的な長い名前が好き) そうでない人はどうしてるのかなぁと思いました。 モジュールとかパッケージとか使うと解決する ? もしくは、レコード表記はあまり使わない ?
qualified無しのimportする奴が悪いということで短い名前での衝突は気にしない import qualified Bar.Foo as Foo Foo.name Foo.length のようなqualified importを使う
299 :
297 :2013/02/24(日) 13:04:40.80
300 :
デフォルトの名無しさん :2013/02/24(日) 14:54:27.14
/.に書き込まれてたこれはどう思う? Haskell のデバッグは絶望的に難しい。従来の手続型言語のようなステップ実行によるデバッグは、あんまり役に立たない。 自分は GHC しか知らないけど、クラッシュした時にスタックトレースすらとれない。 というか、基本が遅延評価の Haskell は原理的にスタックトレースに意味がないので、たいていはどこでクラッシュしたのかすらわからない。 バグの個数は 100分の1になるけど、残り1%のバグが 100 倍強力になって襲い掛かってくる感じ。
自分のプログラムで 「例外も吐かずに」 クラッシュするなら、 FFIで制御が外部ライブラリに行っている時をまず疑うな。 unsafePerformIO で IO モナド外しとかバカな事をせず 普通に Haskell を使っているのなら、 100% に近い確率で外部ライブラリに変な値を渡した事が原因だ。 クラッシュはしないが、計算結果が意図したものではないという場合は、 Debug.Trace モジュールの関数を使って調べれば良い。 俗に言う printf デバッグだ。 Haskell は純粋な部分の関数は切り分けて単独でテストできるから、 俺はむしろ他言語よりデバッグしやすいんだがな。
よく言われるのは遅延評価で空間的、時間的リソースリークがあああとかいうやつ それと無限ループでCoqやAgdaのような隣の芝生に嫉妬することも それともうちょっとghciのデバッガ使いやすくなったらなとか
どんな事が出来たら使いやすいといえるのか、提案すれば?
これは何が問題なんだ? main = print $ sum [0..1000000]
和の公式で求められる
遅延評価のせい sum'ってあったっけ
GHC だと、USE_REPORT_PRELUDE を定義しない限り、 sum の定義は次のようになっている。 sum l = sum' l 0 where sum' [] a = a sum' (x:xs) a = sum' xs (a+x) これって、最後に sum' [] a の a を評価するまで、 (a+x) の計算がどんどん遅延して長〜い加算計算の羅列になったりするの? もしそうなら、seq a $ sum' xs (a+x) で解消できる?
foldl'でおk
遅延評価なくても累積変数使わないとスタックが深くなる。
>>307 よく考えたら、(+) が引数を即時評価して計算するかどうかは、引数の型に依るか。
もし sum の引数が Int 型だったら、
>>307 の (a+x) は即時評価されて、
メモリ内に未評価の計算が 0 + 1 + 2 + 3 ・・・みたいに連なることは無い?
型じゃ式の評価がどのくらい深いか分からんからな。
>>310 コストを考えれ
じゃなきゃお前をC/C++が出来ない難民だと認定する
>>314 コストって何が言いたいんだ?
1000000 程度だったらスタックの深さ的にも動くだろ。
計算量のことを言ってるなら、今言う話じゃない。
サンクってのがあってね。
サンクコストとか書くとダブルミー人具
人具ってなんかエロい
319 :
デフォルトの名無しさん :2013/02/27(水) 21:15:25.24
クイックソートについての質問です。
>>259 の関数だと
*Main> qs [13,14,14,19,13]
[13,13,13,14,14,14,19]
*Main> qs [13,13,15,36,13,15,14]
[13,13,13,13,13,13,13,14,15,15,15,36]
になってしまいます。下の
--filter check (x:xs) = if check x
--then (x:(filter check xs))
--else filter check xs
だったら真にならなかった要素がなくなったリストが出来上がると思うのです。
クイックソートのリストの中身は順番などが関係するのでしょうか?
しない
>>317 落ちる隕石キタ━━(゚∀゚)━━!!!
322 :
デフォルトの名無しさん :2013/02/28(木) 15:43:29.85
おまえらソートしかする事ないのかよ
ソートは知らなかった。
324 :
デフォルトの名無しさん :2013/02/28(木) 19:21:55.79
入門書にソートがあるので勉強してます。所で、 angle :: Float -> Float -> Float angle x y | x > 0 && y > 0= (y / x) / tan | otherwise= error"" のtanがなぜエラーなのでしょうか?
>>324 (y / x) / tan は演算子を使った式だが、これを関数の形にするとこうなる。
(/) ((/) y x) tan
元の式の中央の除算演算子が、関数にした式の最も左側にある関数 (/) だ。
関数 (/) の型は Fractional a => a -> a -> a だ。
この型変数 a には例えば Float 型などが入る。
関数 (/) が第一引数として適用するのは ((/) y x) だが、
x や y が Float 型なので、ちゃんと全体で Float 型になっている。
ところが、ここで関数 (/) が第二引数として適用しようとしているのは関数 tan だ。
この型は Floating a => a -> a であって Float 型ではない。
もう少し優しく言うと、tan :: Float -> FLoat であって、tan :: FLoat ではない。
なので、関数 (/) の型に合ってないよ、という趣旨のエラーが出る。
もし (y / x) / tan ではなく、例えば (y / x) / tan x とかだったら問題ない。
tan x は Float 型なので、この場合の関数 (/) の第2引数として適用できる。
326 :
デフォルトの名無しさん :2013/02/28(木) 20:34:59.46
なるほど、tanには他に引数がいるのですね。 三角形の角度で、xが2、仮に角度が45の時yは2。 ここではその角度Xを求めたいので2tanX = 2 -> tanX = 2/2 -> X = (2/2) / tan or atan (2/2)。 しかしながらtanは他に引数が必要。けどその引数を知りたい.... プログラムの前に数学勉強してきます。 丁寧な説明、ありがとうございました。
>>325 tanに引数がないって言えば終わるのにどうしてそんな長くなった
>>326 常識的に高校くらい出ておけ
>(y / x) / tan
唖然としたわ
>>327 > tanに引数がないって言えば終わるのにどうしてそんな長くなった
Haskellと付き合うなら型(シグネチャ)を常に意識するようになってほしいからです。
あと、起きているエラーの式がどういった式なのかも意識して欲しかったからです。
>tanに引数がないって言えば終わる
Cみたいな言語ならそれで終わるんだろうけど、Haskellだとそれじゃ正しくない
今回のは型が違うって言えば終わる
が、それだけだと
>>326 レベルの初心者では何が何やら分からんだろうから説明長くなったんだろう
331 :
デフォルトの名無しさん :2013/03/01(金) 20:27:05.86
モナドが分からん いろいろな種類のがあって分からん モナドの何が嬉しいのか分からん いろんな説明があって分からん コンテキストの抽象化だというのが一番分からん これまでのプログラミング手法でいうと何がそれに近い? 分かり易い説明キボン どこの説明がおススメ、でも結構
私もモナドは判らない。モナドだけではないwのかも知れないが判らない。
333 :
デフォルトの名無しさん :2013/03/01(金) 20:49:41.32
以前だと、bit誌なんかが、半年位の連載で取り上げそうなテーマだけど、 今はそういう部分が薄くなっているから。
334 :
デフォルトの名無しさん :2013/03/01(金) 21:43:42.51
去年数セミがやっていたけど、あれも、嬉しさは分からないだろな。 bitでやったとしても同じようなものじゃないの? もっと本質的な分かりにくさの理由があるんじゃないかな そもそも嬉しいところはないとかw
直観的に明らかなのがいいとは限らないが 分からないのもなー
分からないことが(たぶん)原因で不便を感じている、 という事でなければ、分からないままでいいんじゃね
>>331 モナドの嬉しさを理解する前に、モナドの具体例はいくつか理解してる?
IO、Maybe、Stateくらい分かってればいい
>>336 そういう言語が他にあまりないから。Zとかは別にすると。
339 :
デフォルトの名無しさん :2013/03/01(金) 22:31:39.50
>>337 うん。もちろん知ってるつもり。他にベキ集合もListも例外も非決定性もw
>>336 クールだなw 分からん者の気持ちがわかってないな
>>338 そういう言語?Z?Zとモナドは関係ないだろ?
340 :
デフォルトの名無しさん :2013/03/01(金) 22:31:56.04
>>331 1.C言語のポインタと一緒で必要以上に難しいと煽られているもの。 2.printfの書式指定と一緒で、実装とか細かいことを気にせずに使い方に集中すればいい。 3.世の中謎に満ちている。気にしたら負けだ。
341 :
338 :2013/03/01(金) 22:34:51.09
>>339 学習する際の話になるけど、
理論的にはさっぽり分からないけど、ともかく進めていくという言語ね。
342 :
デフォルトの名無しさん :2013/03/01(金) 22:57:43.11
>>340 負けたくないんでwこんなコメントうれしいわ。
でもポインタやprintfよりずっと難しいし、世の中の謎ほどの難問でもないと思うし
>>341 これもあんがと。
でもZは集合記法、これでオシマイ、だよね
Haskellに集中するのはおすすめしない コールバック、継続、モナドの順に覚えればいいと思う
Haskellにグローバルな継続はねえよ 限定継続なら作れるけど標準ライブラリに入ってないし
だからHaskellに集中するなって言ってるんじゃないの?w
「モナドが分からん」とだけ言う人は、 複素数が分からんとか微分がわからんと言っているのと同じで、 範囲が広すぎて、こちら側としては何をアドバイスすれば良いのか分からん。 質問の範囲が広すぎると、アドバイスも広く薄くなるし、散漫になる。 モナドの何が分かるようになりたいのか、 まず極狭い範囲の知りたい事をひとつ絞ってくれ。 そうすれば、皆がそれについてピンポイントで濃いアドバイスができる。 それが十分納得できてから、次の知りたい事をまたひとつだけ挙げてくれ。 そうやって少しずつ取り組まないと、たぶん何も得られないと思うよ。
347 :
デフォルトの名無しさん :2013/03/01(金) 23:45:58.08
1.モナドの何が嬉しいの? 2.いろいろあるモナドに共通するのは何?(3則という答えがあるのは知っているが) まずこれらを普通のプログラム経験はある人なら分かるように教えてほしい
1.いきなりそれにこたえるのは無理。ファンクター、アプリカティブファンクターを順番に学ぶといいよ 2.モナド則だけです
do記法を使って(関数型言語のメリットを保持したまま)手続型言語っぽく書ける しかも"<-"がカスタマイズできる。 であってる?
IOではないものを色々作ったのが嬉しいのかな 全部IOでやろうと思えばできるし共通点もわかりやすいが それではIOが過大評価されてしまうので関数型として都合が悪い
IOやSTを使って計算速度が速いプログラムを書くコツが知りたい。
・モナドでこれまでのHaskellライフがどの様に変わるのか
<- は、単にくるんであるものを引っ張り出す記法だからなんか違う。 カスタマイズできるのは >>= の意味、なのかなぁ。
(>>=) も単に引っ張り出す記法のような気がするが 出る杭は打たれるというか、数学的でない説明を潰そうとする力が働く といっても物理的な力ではないので無視することはできる
単に引っ張り出す記法というならどっちもそうだろ 引っ張り出し方をカスタマイズできるだけで
return は値を箱に入れて封をする。 >>= は箱の封を解いて値を取り出す。 どちらも、その方法が外部から隠蔽されている事が肝です。 だから、箱に入れたり取り出したりする時に何か計算(処理)をさせたり、 箱の中の情報の一部だけを >>= の第2引数の関数に渡したり、 そんな事をしてもモナドを使う側から見れば同じ計算に式に見える。 つまり、同じ扱い方ができる。 これが、1.モナドの嬉しい事であり、 2.いろいろあるモナドに共通する事柄です。 その同じ扱い方ができる保証を与えるのがモナド則です。
>>356 結局ユーザーとしてはこれだけ知ってればいいんだよね。
敷居高く見せるために難しくモナド則とか名前付けてるけど結局はinterfaceとかダッグタイプでしかないってこと?
>>358 (よく言われるけど)敷居高く見せるために、という理由の根拠は?
Haskell の歴史を概略した論文を読んでも、
敷居高く見せる必要があったとは読み取れないよ。
文法では規定できない規則をプログラマにお願いする際に、
その規則を呼ぶキャッチーな名前がある方が便利だよね。
いちいちルールAとルールBとルールCに従ってくださいと言うよりも、
モナド則に従ってくださいという方が簡単だ。
Monad クラスにしても、Haskell という言語の中では、
他の Functor クラスや Show クラス、Eq クラスなどと同じ
ごく一般的な普通のクラスだ。
それに担わせたかったある役割を実現する(表現する)方法として、
たまたま計算機科学におけるモナドの概念がうまくマッチしたから、
その概念や名前を拝借して Monad クラスという名前を付けただけ。
(ある役割というのは、初めはIOを純粋関数型らしく上手く扱う事だったと言う)
まあモナドって名前はあんまり良くないよね
>>360 まぁ、それは人によりけりだね。
この名前から初心者を寄せ付けないオーラを感じ取る人もいるだろうし。
私は高尚感はそれほど感じないな。
Monad クラスのインスタンスを
モナディック ファミリーと勝手に呼んで親しんでる。
>>358 参照透明性を保とうとすると、アルゴリズムの教科書なんかで良く出てくる
タイプの逐次処理なんかをどう書くかという問題がでてくる。
逐次処理のうち、あるものは fold 系でまとめることができる。
部分的な結果をつなぎあわせて最後の計算結果にするタイプの
アルゴリズムは必ずしも fold 系で記述できないが、
多相型Fの型コンストラクタが関手であり、さらに
モナドであるばあいのKleisli射の合成として表せるタイプの計算に
対しては、その一連の計算があたかも命令を連ねて値を作っている
かのように人間に感じさせるシンタックスシュガーが用意されている。
要するに、
・do 記法自体はむしろ敷居を下げるために導入された。
・使い方、ではなくデザインの背後にあるロジックを知ろうとすると圏論が出てくる。
わけだ。計算の抽象化うんたらってのはMoggiあたりが言い出したことで、
知りたかったら論文読めばいいし、知らなくてもHaskell使うのに支障はない。
>>360 モナドって呼ばれる前は数学の中で Triple と呼ばれていた。いくらなんでも
一般名詞すぎるのでマクレーンがモナドと命名した。
そもそもの始まりとして、カテゴリーという名称自体アリストテレスの範疇論から
名前を借りてきており、この辺はマクレーンが最初基礎論を専攻しようと
した哲学的な傾向というか憧れというかコンプレックスというかそんなものの反映。
モナドが酷い名前だというのはまあ同意するけど「りあむ」よりは良い名前だと思うよ。
参照透過性を保つっていう観点だけなら、モナドより一意型のほうが分かりやすいと思う
F#だとコンピュテーション式だっけ
モナドをわかりやすく解説できるかた 解説よろしくです
すごいH本買って頭から読め、絶対それが一番速いから 基礎は知ってるならファンクタからでも
本ってモナドはしょってない?
むしろ半分くらいモナドの話だ、あれは
入門書2冊程よんだけど、モナドが何なのか結局分かんなかった
モナドとは特定の人物・血縁を意味する言葉ではなく生き方そのもの モナドを理解するためにはこのことにまず気付かねばならない
>>366 >>346 でも言ったが、モナドの何が知りたいのか、具体的に、
できればひとつに絞って質問してもらう訳にはいかないのかな。
それと、モナドをHaskellプログラマとして使う側に沿った説明は、
このスレでも色んな方がされている。
私も稚拙だが
>>356 で肝の部分を少しだけ説明したつもり。
**番のレスの〜の意味が分からんとか、**番のレスの説明をもう少し詳しくとか、
そんな感じで質問してくれると、アドバイスする方としては大変助かるのだが。
>>372 モナド則についてとStateモナドについてお願いします
>>356 を読んでもそれがStateを管理するのにどうつながるのかよく分かりませんでした
374 :
デフォルトの名無しさん :2013/03/02(土) 19:43:17.74
356以外はなぜかだれも347に答えてないんだな
>>356 その喩えは確かか?
箱って何?なぜわざわざ箱に入れるの?
隠蔽はモナドに限らない常套手段なのでそれが肝と言われても?
>そんな事をしてもモナドを使う側から見れば同じ計算に式に見える。
何と何が同じ計算に見えるの?
>>374 ここはべつにお前の質問に答えるための板じゃない
肝心なのは理解することじゃない。 理解したつもりになること。
>>373 順に質問の幅を狭めて具体化させるぞ。
モナド則の何が知りたい。
Stateモナドの何が知りたい。
ていうかこの人前も居たような… 自分で考えずに全部オウム返しで漠然と質問してくるから話にならない
379 :
デフォルトの名無しさん :2013/03/02(土) 19:53:31.12
>>375 347、370、373等の質問に答えてないなと言っただけだ。おれはそのどれでもないが
だからよほど難しい質問なのかと思った
380 :
356 :2013/03/02(土) 20:00:16.48
>>374 会話しやすいように、私の元の発言のレス番を名前に入れておくな。
> その喩えは確かか?
申し訳ない、
>>356 では言い忘れたが、
私が個人的に抱いているイメージなんで、人によっては違うと思う。
> 隠蔽はモナドに限らない常套手段なのでそれが肝と言われても?
そう、情報を隠蔽する方法は Monad クラス以外にもいろいろある。
その方法のひとつが Monad クラスというとして標準ライブラリに用意されており、
また、その方法が特別有用なので文法上も特別扱いされている。
> 何と何が同じ計算に見えるの?
(Monad m) ==> m a 型の値 x と、
(Monad m) ==> m a -> (a -> m b) -> m b 型の関数 f があるとする。
x >>= f という式は、Monad クラスの「どのような」インスタンス型でも成り立つ。
例えばリスト型だろうが Maybe 型だろうが、IO 型だろうが。
同じ計算に見えるというのは現象で、大事なのは同じ扱い方ができる、という事。
すけべ本のリスト内包表記のとこまでやっと読み進めた俺にもわかりやすく
おかしくね?
383 :
356 :2013/03/02(土) 20:11:10.78
>>374 見落としてた。
> 箱って何?なぜわざわざ箱に入れるの?
箱というのは、return x という式で値 x をモナド化させると言ったり、
x をモナドでかぶせると言ったり、そういう言い回し(しないかな・・・)を、
私は「箱に入れる」とイメージしているだけだ。
なぜわざわざ箱に入れるのか、つまり何故モナドにするのかと言えば、
プログラマの視点から言えば、箱の中身を触らないようにするためだ。
オブジェクト指向のクラスで言うところの、private メンバ変数にして、
外部から勝手に触らせないようにするためだ。
たとえば State モナド。
このモナドの箱の中には、ユーザーが return 関数で入れた値の他に、
状態を表す値も密かに入れられている。
ユーザーによってその状態を表す値が勝手に書き換えられたら、整合性がとれなくなる。
だから State モナドは状態を表す値を隠し、
特別に用意された関数を通してしかアクセスできないようにしている。
モナドとはなにか?なんて問いに本気で答えるには圏論の話をしなきゃいけないんじゃないの? 俺なんかはその辺は諦めて実際の用法に集中してるんだけど
モナドはコンテナって言うのはよく聞くね だけどコンテナに値突っ込んだり出したりって副作用じゃないの?って思ってしまう
386 :
356 :2013/03/02(土) 20:18:06.70
>>382 で気づきました。
>>380 の説明の関数 f の型はおかしいですね。
(Monad m) ==> a -> m b です。
すいません。
> 箱って何? Monadのインスタンスは種が*->*の型コンストラクタであり 既存の型を包みこむように動作することから イメージしやすいように箱とかコンテナが良く引き合いに出される
Javaで言うところのint->IntegerのBoxing?
種の概念のことを言ってるならJavaだと総称型が近い
最終的にAgdaとHaskellはシンクロするんです?
391 :
デフォルトの名無しさん :2013/03/02(土) 20:35:05.09
>>384 いや圏論を持ち出してもわからなさは同じだと思う
>385 プログラムの意味論における「状態が変化する」ことを副作用と言っている。 もっと広く、環境が変化すると言ってもいい。 状態が変化するとか環境が変化するというのは、意味上メモリの内容が変わったり、 コンソールに文字を表示させる事でコンソールの内容が変わったりといった事。 (意味上と限定したのは、実際 GHC は内部でメモリの内容を書き換えるかも知れんから) コンテナに値突っ込むとか、箱に入れるとかはあくまでイメージなので、 その操作自体に副作用があるとか無いとかは関係ない。 その操作の時に中で何が行われるかによる。 そうイメージされる現象によって状態・環境が変化しなければ副作用は無いと言えるし そうイメージされる現象によって状態・環境が変化すれば副作用はあると言える。 例えば State モナドは環境が変化しないので副作用は無い。 IO モナドは環境が変化する(可能性がある)ので副作用がある(可能性がある)。
393 :
デフォルトの名無しさん :2013/03/02(土) 20:48:32.92
>>356 ありがと
>私が個人的に抱いているイメージなんで
いやそれで十分
>x >>= f という式は、Monad クラスの「どのような」インスタンス型でも成り立つ
うん。だけどそれがどれほど嬉しいのかが分からん
>なぜわざわざ箱に入れるのか、つまり何故モナドにするのかと言えば、
>プログラマの視点から言えば、箱の中身を触らないようにするためだ。
>たとえば State モナド。
>ユーザーによってその状態を表す値が勝手に書き換えられたら、整合性がとれなくなる。
>だから State モナドは状態を表す値を隠し、
>特別に用意された関数を通してしかアクセスできないようにしている。
ここは違うんじゃないの?箱は隠蔽のためではないでしょ?
>>385 出した結果がブレるのが副作用
出さなければ副作用はない
コールバックのように自分では呼び出さないようにする
HaskellでRPGを作るにはどうすればいいです? 例えば主人公がキー入力によって移動して ある位置に到達すると会話シーンなどのイベントが始まるような C脳なので主人公が移動するためには座標を管理する変数を書き換える必要があるなとなってしまう
396 :
デフォルトの名無しさん :2013/03/02(土) 21:30:09.70
俺のなかでは、モナドは世界線の移動装置なんだが・・・。
398 :
356 :2013/03/02(土) 21:35:07.04
>>393 > ここは違うんじゃないの?箱は隠蔽のためではないでしょ?
いや、私のイメージでは隠蔽なんだが。
f :: a -> State s b を作れば >>= で簡単に箱から情報を取り出せる。
もっといえば、do 記法の中で <- を使うだけで情報を取り出せる。
そういう意味では隠蔽していないと言えるかもしれん。
でも、State モナドは return x でユーザーが箱に入れる情報の他に、
「状態を表す情報」もこっそり一緒に箱に入れている。
この「状態を表す情報」はユーザーは勝手に取り出したり書き換えたりできん。
これは情報の隠蔽と言えると思うのだが、どうだろうか。
ぶっちゃけて言えば、State や IO がモナドなのは私も理解できるが、
Maybe や Either などがモナドである必然性はちょっと説明できん。
たまたま Monad クラスに fail 関数があるから、かろうじて
Maybe や Either などがモナドであるメリットはあるが・・・
そもそも Monad クラスに fail 関数がある事自体私も意味が分からん。
399 :
デフォルトの名無しさん :2013/03/02(土) 21:35:47.93
haskellは副作用が無いと聞いたんですけど、IOモナドは副作用が出るのですか? そもそも副作用がよくわからない。 f :: Int -> Int f x = 2 機能に影響されない se :: Int -> Int se x = se x + 1 機能に影響される こんなヤツ?
400 :
デフォルトの名無しさん :2013/03/02(土) 21:36:07.78
>>395 プログラム作るだけならIORefとかでぐぐったらいいと思う。
>>396 つまりHaskellでゲームを作る場合
・関数Fを評価するとその関数はモナドを返す
・そのモナドの中身にはステーを反映した関数F'のインスタンスが定義されている
・次のフェーズではF'を評価してF''のインスタンスが格納されたモナドを返して
・・・・
この世代交代を毎フレームするってこと?
>>395 方法はいくつかある。
本当にそのまま座標を管理する変数を書き換える事もできる。
Haskellにはメモリの書き換え処理をする関数も標準ライブラリで用意されている。
他には、移動する度に古い座標の変数を破棄し、新しい座標の変数を作ることもできる。
破棄した変数(を納めたメモリ領域)はガベージコレクタによってそのうち回収される。
こちらは、副作用は伴わない。
403 :
デフォルトの名無しさん :2013/03/02(土) 21:43:45.10
>>401 俺はそう理解している。ちなみに独習でHaskell歴半年。察してくれ。
モナドってこういうもの? int x; int getter(){return x;} void setter(int a){x = a;} void f(int* g(), void* s(int)) { s(g() + 1); } f(getter, setter);
俺の人生 19xx年:生まれる 2013年:モナドがわからない ←いまここ
>>399 Haskell にも副作用はある。
プログラムソース中の、副作用がある部分と、副作用が無い部分が
明確に分離されるのが Haskell。
Haskell のプログラムで両者が混じることは、普通は無い。
> そもそも副作用がよくわからない。
>>392 でも少し説明したが、もっと簡潔に言うと、
下記の2つの事が両方とも護られていれば、純粋な関数、つまり副作用は無い。
・関数 f について、a == b ならば f a == f b である。
・関数 f について、計算以外の事をしない。
少なくとも一方が守られなければ、たいていは副作用がある関数だと思って間違いない。
>>404 そのゲッターとセッターが、型 int に結びつけられており、
かつ、そのゲッターとセッターがプログラマから隠されていれば、
Haskellのモナドの機能の一部は似ている、と言える。
メモリの破壊的な状態書き換えを副作用と呼ぶなら、 少なくとも実行時には副作用起こりまくり。
410 :
デフォルトの名無しさん :2013/03/02(土) 22:40:28.50
Excelシート : 副作用なし。モナドを使わないHaskellプログラム Excelシート+VBA : 副作用あり。モナドを使うHaskellプログラム
関数の中で破壊したメモリを関数の外で(関数の戻り値として以外に)参照しないなら、 その関数は副作用を持たない
>>410 セルの内容書き換えられるがな(´・`・ω)
>>409 そういう事もあり得るから、
>>392 で意味論におけるとか、
意味上とか言って限定したんだがなぁ
>>398 たとえばStateモナド(を実装した代数データ型のインスタンス)から、パターンマッチで内部状態を取り出すことが
できるよね。
モナドであることの条件にこれを禁じるルールはないと思う。
>>413 意味論の側面は「参照透過性」と表現すると思う。
>>414 そのパターンマッチは m >>= f の f の中でしかできないんじゃないの?
417 :
356 :2013/03/02(土) 23:06:56.98
>>414 data や newtype で定義した型の値コンストラクタが公開されていれば、
それが Monad クラスのインスタンスだろうがなんだろうが、
その値コンストラクタでパターンマッチできるよ。
値コンストラクタが公開されていなければ、
パターンマッチでは取り出せない。
モナドの話とは関係ないと私は思ってるんだけど、なんか関係あるかな?
418 :
デフォルトの名無しさん :2013/03/02(土) 23:08:37.40
>>412 ExcelシートのCellに"=2+3"と書き込むことは
Haskellでいうところの定義だろ?
*.hsファイルにエディタでx=2+3と書き込むのと一緒だと思う。
この定義されたセルをプログラムから書き換えるには
VBAを使うしかない。
419 :
356 :2013/03/02(土) 23:11:16.90
>>414 あと、モナドで隠蔽するのは中の値だけじゃなく、
箱に値を入れる時にした計算や、箱から値を取り出した時にした計算も、
一緒に隠蔽するよ。
>>418 それ(Haskellの何をExcelの何で喩えているか)を始めにはっきり言わないと、
たいていの人には話は通じないよ
>>417 > モナドの話とは関係ないと私は思ってるんだけど、なんか関係あるかな?
俺もそう思ってるが、君が
> これは情報の隠蔽と言えると思うのだが、どうだろうか。
と言っているので。
422 :
356 :2013/03/02(土) 23:40:21.81
>>421 ごめん、意味がよく分からない。
return 関数や >>= 演算子の実装で情報は隠蔽されるよね。
値も、その計算も、他の計算も処理も隠蔽されるよね。
そういう事を隠蔽と言ってるんだけど。
そのことと、たまたま data で定義した型の値コンストラクタが公開されている
という事による情報の公開は、モナドによる情報の隠蔽とは何も関係ないよね。
この一連の会話は、モナドの話だよね?
>>358 無知蒙昧なプログラマがHaskellに一体なんの不義理をしたんだよ
モナドのうれしさは ■具体的な処理をブラックボックスとして扱うこと。 ■個々の処理をつなぐことができること(>>=)。 ■処理の結果を、次の処理以降では、ある意味でグローバルな変数 (自由変数) として使えること。(実際のスコープは Maybe や IO などのタグ (圏) の中に限定される) モナドの枠組みが色々なものに当てはまるからわかりにくいけど、本質的には上記の点が共通しているはず。
例えば、手続き型言語では ■行を実行する ■結果を変数に代入する (しない場合もある) ■後ろの行は前の処理結果 (変数の値) を利用して計算したりする。 なんか、モナドの役割と対応つきそうでしょ? だから、do を使う関数では手続き型言語っぽい書き方ができる。 私の理解はこんな感じです。 間違ってたらごめんね
モナドじゃなきゃ出来ないことってあるの?
実用的なこと全て
むかしはモナドなかったんよ
>>427 Haskellにおけるデザパタみたいなものなので、可読性が低くて良いなら
モナドを使った処理は全てモナドなしで書ける。(現在の入出力のように
最初からモナドで書かれたライブラリはのぞく)。
431 :
デフォルトの名無しさん :2013/03/03(日) 09:10:07.41
>■行を実行する >■結果を変数に代入する (しない場合もある) >■後ろの行は前の処理結果 (変数の値) を利用して計算したりする。 結局,モナドとは,手続き型言語ではふつうにやることを 関数型でもできるようにするデザパタのことと思えばよいの?
そういう用途もある
433 :
デフォルトの名無しさん :2013/03/03(日) 10:17:53.94
デザパタというのがGoFのもそうだがまた胡散臭いんだこれがw
staticおじさん乙
今時デザパタ如きが胡散臭いってどこの原始人だよ
デザパタとアンチパターンを分ける基準がないから胡散臭い 良いか悪いか判断しないで用例を集めるだけにするべきだった staticおじさんも良いか悪いかは別としてそういう書き方もありうると言うべきだった
437 :
デフォルトの名無しさん :2013/03/03(日) 11:49:15.77
>今時デザパタ如きが胡散臭いってどこの原始人だよ これはどういう意味だ? 今はもう、デザパタどころではない胡散臭いのが出回ってるってことか それともデザパタが偽モノなのはとっくに常識になってるってことか それともまさか今時デザパタを信奉してんじゃないだろ?
438 :
デフォルトの名無しさん :2013/03/03(日) 11:55:51.70
>そういう用途もある 他の用途もいろいろあるというのでまた分からなくなるわけだ
ageる奴はバカの法則が見事に的中してるし
>>437 信奉の意味が分からない
状況に応じて使えそうなら参考にする、それだけのもんだろ
消化した上で使えないと判断するのは勝手だけど、胡散臭いなんて次元で語られる時期はとうに過ぎてる
その意味で原始人
>>431 Haskellに Monad クラスのインスタンス型がある理由は、本質的にはそれだよ。
特に IO モナドね。
その Monad クラスのインスタンスを引数にとったり返したりする関数に、
いろいろ便利なものがあるから、手続き型言語の事は忘れて、自分で色々応用すれば良いよ。
ただ、
> 手続き型言語ではふつうにやることを
> 関数型でもできるようにする
なんか「関数型ってこんな簡単な事をするのにも面倒だね」という
見下した感じを少し受けるのは私だけだろうか。
モナドの仕組みを組む人たちは面倒というか、そりゃ大変だったろうけど、
それを活用する我々プログラマにとっては、全然面倒じゃない。
むしろ、逆に純粋関数型でこんな事もできる、と幅が広がる。
なんの御利益があるかと問うこと自体、ある意味見下していると絡めなくもないけど それは目くじらを立てても仕方ないだろう
「普通のプログラム経験はある人なら分かるように」なんて言っちゃうのは、普通の(手続き型)プログラム経験の延長上に関数型を捉えている感じでアレ
foldl f e = ($ e) . foldr ((.) . flip f) id みたいにfoldlをfoldrで定義する練習問題みたいなのあるじゃん こういうのを型を比べたり簡約したりでパズルみたいに書くのは出来るんだけど理屈はわからない で色々考えた結果algebra of programmingにあるようなreverseがListから逆順リストへの自然変換とかいうの見方を使って foldrそのものが関手μX. 1+A×X-代数のcatamorphismなんだからfoldlはμX. 1+X×A-代数のcatamorphismとみなして F代数の圏でμX. 1+A×XとμX. 1+X×Aに同型っぽいのがあって、それをfoldrやfoldlに作用させると 最初に示したfoldlを計算で導きだせるんだろうなと思うんだけどそのF-代数同型射っぽいものが何か解らない 何か知ってる人教えてください
foldl f e = ($ e) . foldr (flip (.) . flip f) id だったかもしれない
446 :
デフォルトの名無しさん :2013/03/03(日) 18:45:44.23
>>441 >>442 >>443 >>443 は手続き型を見下しているようだが
おれは手続き型、関数型のどちらかを上とか下とか思っているわけじゃない
同じ土俵で見ようとしているだけだ
御利益を問われるのは当たり前のことだ。貴族じゃないんだから
代数データ型やパターンマッチがあり、カリー化があって 簡潔なコードが書き易く、静的型検査が強力で、 副作用のある部分と無い部分をキッチリ分離できる そんな言語が、副作用のある部分を 手続き型と同じように書けるんだから それだけで御利益あるだろ
>>446 >>431 の
> 手続き型言語ではふつうにやることを
> 関数型でもできるように
という言い方がなんかなぁ、と感じる。
「ふつう」なんてわざわざ書く(しかもひらがなで)ところも、
なんとなく馬鹿にしている感じがしないでもない。
例えば、手続き型言語の構文を関数型でも使えるようにするデザパタか、
と問われるなら、べつに嫌な感じはしないが・・・
手続き型と同じように書けるのはIO型 手続きじゃない部分でもdo記法とか使えるのがMonadクラス
450 :
デフォルトの名無しさん :2013/03/03(日) 19:26:19.16
>>448 それは悪かった。そんなつもりはまったくなかった。
しいて言えば、こっちがモナドに馬鹿にされてると感じてるかもしれん
>>446 手続き型を見下してなんかいないよ
手続き型プログラミングと関数型プログラミングの間に存在するパラダイムの壁が認識できていないのではないか、ということだよ
452 :
デフォルトの名無しさん :2013/03/03(日) 20:42:19.78
>>451 手続き型はもちろん、モナド込みの関数型でも、どちらのパラダイムも満足
できるものではないと思っている。だからパラダイムとか壁とかという表現も
なんだかなと思うのだ
>>452 パラダイムに満足できるかどうかと、
パラダイムに違いがあるかどうかという事とは、
全く別の事だと思う。
それとも、両者のパラダイムに満足できなければ、
両者のパラダイムにたいした違いは無いという事になるの?
>>443 >>451 は、パラダイムにはっきりとした違いがあるのだから、
一方のパラダイムをもう一方のパラダイムの延長で考えるのではなく、
違いを認識して別物として考えないといけないのではないか、
と言っているのだと思う。
454 :
デフォルトの名無しさん :2013/03/03(日) 21:40:53.72
>それとも、両者のパラダイムに満足できなければ、 >両者のパラダイムにたいした違いは無いという事になるの? うん。第三のパラダイムから見ればそういうことになるね。 モナドだってそう思ってるんじゃないの?
>>454 満足できるかどうかは個人の主観の問題だよな。
違いがあるかどうかは視点の問題だよな。
前者の結果によって後者が影響されるのはおかしくないか?
457 :
デフォルトの名無しさん :2013/03/03(日) 23:12:13.13
>>447 >>455 >副作用のある部分と無い部分をキッチリ分離できる
>そんな言語が、副作用のある部分を
>手続き型と同じように書けるんだから
モナドの御利益はこれに尽きるとのことなので、
スマンが、そこが分かるこれぞという例題を一つ教えてもらえんだろうか
> それだけで御利益あるだろ これを > モナドの御利益はこれに尽きるとのことなので、 こう解釈する時点で、悪意があることがハッキリしたね
頭が悪いだけかもしれん どうしても自分の理解できる範囲で収めたがってるように感じる
460 :
デフォルトの名無しさん :2013/03/03(日) 23:27:50.12
悪意はないよ
>>457 import System.Random
main :: IO ()
main = do
v <- randomIO :: IO Int
let a = double v
print a
double :: Int -> Int
double x = x * 2
main 関数は戻り値が IO () 型で副作用がある。
double 関数は戻り値が Int 型で副作用がない。
副作用がある関数とない関数、それぞれの定義が必然的に明確に分かれる。
(ただし変な事をしない限り)
462 :
デフォルトの名無しさん :2013/03/03(日) 23:37:32.74
463 :
デフォルトの名無しさん :2013/03/03(日) 23:45:29.84
>>461 >副作用がある関数とない関数、それぞれの定義が必然的に明確に分かれる
これだけだとvoidとintの区別と同じだねと思うよね。もちろん悪意なんかないよ
え?馬鹿? もちろん悪意なんてないよ
>>463 > voidとintの区別と同じ
もっと詳しく説明していただけないでしょうか。
できるだけ例を分かりやすく改善させたいと思います。
Int 型を戻り値とする関数の中で
副作用がある処理はできないという事を簡単な例で示したつもりです。
C 言語の int 型を戻り値とする関数では、
中で printf 関数を呼べたりできるので、
Haskell のものとは全く違うと思うのですが。
Haskell Report 2010 読めば良い。
>voidとintの区別と同じ 流石にアホすぎるわ 説明求める前に入門書でも読めよ
>副作用がある処理はできないという事を簡単な例で示したつもりです。 何が「できない」か説明したくなるのは静的型だから当然ではあるけど やっぱり何が「できる」かを堂々と言える動的型を先に習得して その後でHaskellをやった方が話が早いんじゃないかと思う
動的型だの静的型だのは副作用と関係ねーよ それとも静的型なら再代入ができなくなるのか
無駄にプライドの高い中学生みたいな手続き脳&スパゲッティ脳が居る
perl忍者最近見ないな
472 :
デフォルトの名無しさん :2013/03/04(月) 07:01:52.07
>>465 >Int 型を戻り値とする関数の中で
>副作用がある処理はできないという事
なるほど、これは分かる。関数型だからね。
しかしそれなら、Cでもコンパイラでチェックしようとすればできることだ。
むしろmainの方が本質的なのか?
>>468 >>457 で求められたのは次の要素を含む例でした。
>副作用のある部分と無い部分をキッチリ分離できる
>そんな言語が、副作用のある部分を
>手続き型と同じように書けるんだから
まず、関数 double 内では副作用がある処理はできないことで、
副作用のある部分と無い部分をキッチリ分離「できる」事を示しています。
そして、main 関数の中で副作用がある処理を
手続き型と同じように「書ける」事を示しています。
「できる」「書ける」ことを例として示しましたが、
分かりづらければ、具体的に何処が分からなかったか指摘してください。
改善します。
>>472 コンパイラ依存の話をしているのではなく、
言語としての仕様の話をしているのだと思っていました。
それは私の勘違いでしょうか。
>>472 Cコンパイラは次の関数ポインタを受け取る関数
int twice(int (*f)(int), int x) {
return f(f(x));
}
が副作用があるか無いかを、どうやって知れば良いの?
渡される関数ポインタfがどんなものか分からないのに。
それとも、関数ポインタが渡されるときは、常に副作用があると考えるの?
なお、Haskellの場合は、副作用の無い関数として定義できるよ。
twice :: (Int -> Int) -> Int -> Int
twice f = f . f
Haskellのコンパイラは副作用の有無をどうやって知るの?
知るも何も、Haskellに副作用は存在しないから
分かってる人には当たり前なのかもしれないが > double :: Int -> Int > double x = x * 2 これを > 関数 double 内では副作用がある処理はできない こう説明されても、なぜできないのかサッパリ分からんぞ?
それは単に副作用とは何かを理解していないだけでは? そもそもHaskellは、副作用のある関数を書くことが文法上できないのだから
元々「副作用」って言葉に明確な定義なんてないだろ。アホか
>>479 できない理由として考えられる物は二つ
・わざとできないように公理系を作ったから
・公理をいくら変えてもできないものはできないから
後者は科学
前者は科学ではないかも
流れ全く読まずにドヤ顔レスするやつが定期的に湧くね、このスレ
↑ドヤ顔レスの一例です
例えば画面への出力を副作用と呼ぶなら、その時に”副作用でない”、意味のある処理って何?って話だな。 世間一般でいう副作用って、本来は不要なものってイメージがあるから。
>>485 言語によっては、GCを強制的に掛けることができるものがある。
時系列 t1, t2 を考えて、強制GCの応答速度が t1,t2で異なるとすると、
ほとんどの計算に副作用があることになる。
プログラミング言語の文脈では、たとえばCの規格の用語である「副作用完了点」のように、 世間一般の用語とは別に、意味がある術語だから。
関係ないことを証明せよ
>>488 少なくとも
>>485 はReturn 以外に何かプログラマに影響を与えるものが
残されるのが副作用という解釈のように読めたから。
>>484 そんな脊髄反射レスするほど悔しかったのか……
お前らが何について話したいのか全く分からん
>>493 >>485 は功利的な価値のあるものが主作用であって、副作用と呼ばれて
いるものが主作用なのではないの?と訊いている。
関数の副作用について話してるんじゃないのか? 関数の主作用は関数の戻値 戻値以外に何か意味のある作用があればそれが関数の副作用
このおっさん副作用も知らんで やたら偉そうに質問してくるのが凄いよな
499 :
498 :2013/03/04(月) 12:33:47.60
ごめん。「何か意味のある」だった。
>>494 そこで静的型が関係してくる
returnする型を静的に宣言したり解析したりするから主作用
そういうことをしてない方が副作用
してない方が主になったら静的型が衰退するから
副作用の定義なんか誰も聞いてないのに、どうしてこうなった?
わかったぞw頭のおかしい奴が2匹いるw
最後に返す型がIOじゃないと作用しないんじゃね letとかでIOの関数定義したとしてもただの定義だから動かないからin以降でその関数呼び出すことになる 結局元の関数の型はIOになる
Haskellのモナドが意味無いものという結論が欲しいので、 副作用のある部分と無い部分をキッチリ分離できるというモナドの特性を否定するために、 副作用について議論をしたいと思います
いや、意味はあるが意味を求めた代償として不自然になる 自然は不変だが不自然は変化しやすいので気をつけよう
>>501 突然「お前は副作用を理解してない」とか言い出すやつが来たから
508 :
493 :2013/03/04(月) 13:41:19.16
で、結局モナドてなんなの?
暗殺集団だろ
IOを中心とする型の集合
自己関手の圏のモノイド対象
手続き処理を記述するための汎用性の高い抽象クラス 具象化する際にいろんな仕組みを多重的に組み込める
手続きはIOだけ IO以外のモナドは、演算子オーバーロードで手続きのように見えるだけ
m>>=fのfが手続き的に順番に評価されていくのがすべてのモナドで基本じゃないの?
Monadは型クラスで、型クラスはオーバーロードしかしないよ
それがどうした
誰も突っ込んであげなかったようなので僕が処理しときますね
>>510 それはモサドやろが!
518の優しさに泣いた
520 :
デフォルトの名無しさん :2013/03/04(月) 20:01:38.17
Haskellに副作用がないなら、C言語にも副作用はないといえるのでは? C言語を、ソースコードと実行ファイルを結び付ける関数とすれば、そこには副作用はない。
eval は Env と f を引数に取る。 eval の後に Env が変化するとき、それを副作用と呼ぶ。
>>520 だから、それは副作用をどう定義するかによる。
と今までいくつかのレスで言われていますが、見ていませんか?
あなたの定義ではC言語にも副作用はないと言える。
しかし別の定義ではそれは成り立たない場合もある。
普通、「Haskell は副作用のある部分とない部分を明確に分ける」
と言った場合の副作用は、たいていのHaskellプログラマの共通認識として、
C言語にも副作用はないとは言えないような定義だと思う。
ある結果 (型など) を期待した時に 期待を裏切るというか期待と無関係な副作用が問題になる 期待がなければ主作用も副作用もない
525 :
デフォルトの名無しさん :2013/03/04(月) 20:45:42.34
副作用の有無で、Haskellと、C言語などの他の言語を切り分けるのは難しいと思うよ。 副作用という言葉について、よほど恣意的で狭い定義を作らない限りは。 でも「参照透過性」なら、切り分けられるだろう。
526 :
デフォルトの名無しさん :2013/03/04(月) 21:05:55.56
>>473 遅くなったがありがと
>まず、関数 double 内では副作用がある処理はできない
これはgoodだが、Cでもできる(モナド固有の利点ではない)と472で言った。
>副作用がある処理を手続き型と同じように「書ける」
これももちろん、Cでもできる。
結局、どちらもCでもできることだがなあ、というのが現時点での感想。
どうなの?
>>474 >コンパイラ依存の話をしているのではなく、
>言語としての仕様の話をしているのだと
うん。言語としての仕様の話でいいです。
コンパイラ依存の話をしたつもりはないんだが。
527 :
デフォルトの名無しさん :2013/03/04(月) 21:10:07.17
間違った >これはgoodだが、Cでもできる(モナド固有の利点ではない)と472で言った。 (正)これはgoodだが、Cでも、できないようにできる(モナド固有の利点ではない)と472で言った。
>>526 >>475 のC言語のコードで副作用のある関数を渡したら
コンパイルエラーになる(警告でもいい)コンパイラを教えてくれ
無いなら、CでHaskellと同じことはできてない
>>526 たぶん、私のレスが勘違いをさせた原因なのでしょう、申し訳ないです。
Haskellでしかできない事だ、とは私は言っていないんです。
副作用のある処理、特に IO 処理をHaskellで表現する際に、
Haskellの利点(型安全、遅延評価、純粋性など)を
できる限り壊さず、かつ使いやすい方法は無いかと模索していたところで
モナドのアイデアを閃いたのが、もともとの発端だったと思います。
閃いたというよりは、出会ったと言った方がより正確ですが。
この辺りの経緯は、論文「A History of Haskell」に少し載っています。
ですが、考えてみてください。
副作用のある処理って、C言語ではできないのでしょうか。
Haskell の特徴なのでしょうか。
違いますよね、むしろC言語なら「普通にできる」事です。
副作用は、実用的なアプリケーションを作るのにまず間違いなく必要なものです。
Haskellは実用的になるように目指した言語なので(上記論文参照)、
Haskellでも「手続き型言語のように」副作用が絶対に必要です。
それを、Haskellの利点を壊さないように取り入れるのに使ったアイデアがモナドです。
モナドのアイデアが採用される前は別の方法でIO処理をしていました(上記論文参照)
したがって、C言語でもできるよね、と感じるのはむしろ当たり前です。
C言語でできる事をHaskellでも、といって取り入れた機能なのですから。
だから本当は、副作用のある処理ができる事がモナドの特徴なのではなくて、
副作用のある処理が「Haskellの良さを壊さずに」できることが特徴なのです。
副作用の部分をきっちり分けることでHaskelの良さを壊さない、
型システムになじませることでHaskelの良さを壊さない、ということです。
530 :
デフォルトの名無しさん :2013/03/04(月) 21:59:42.46
>>529 丁寧な説明ありがとう
>だから本当は、副作用のある処理ができる事がモナドの特徴なのではなくて、
>副作用のある処理が「Haskellの良さを壊さずに」できることが特徴なのです。
はい。そうなのだろうと思います。それは分かります。
>副作用の部分をきっちり分けることでHaskelの良さを壊さない、
副作用の部分を分けることは、Cの場合でもvoidとintなどの区別でできると
前に言いました。「きっちり」というところがHaskellとCとで違うという
ことでしょうか?しかし少なくとも先のdoubleの例題ではそんなに違いは
見えないのですが。
>型システムになじませることでHaskelの良さを壊さない、ということです。
この点も(たぶん)分かってると思います。
531 :
デフォルトの名無しさん :2013/03/04(月) 22:09:30.20
>>530 Haskellは参照透過な形で副作用を含む処理を表現できるけれども、
C言語では、ほとんどの場合、参照透過な形では表現できない。ってところでは?
529ではないけれど。
532 :
デフォルトの名無しさん :2013/03/04(月) 22:10:43.57
>>528 おもしろい例題なので返答を考えていた所だったが時間がないので
そのうちにということにしてくれ。すまん。
ただこの例題は、もとのモナドの問題と直接関係ないと思うし、
現実のCと比べることもあんまり意味はないと思う。
ポインタというのもなんだかなだし。今日はそんなところだ。
533 :
デフォルトの名無しさん :2013/03/04(月) 22:18:02.78
>>531 コメントありがと
>Haskellは参照透過な形で副作用を含む処理を表現できるけれども
ごめん。それが分からんのだ。
なにかこれぞというプログラム例はある?
doubleの例がそれかい?
>>532 ポインタが出てくるのは、Haskellのクロージャに近いものが
Cでは関数ポインタしか無いからだし、
間違って副作用のある関数を渡せないという例なんだから
副作用のある部分とない部分を明確に分けるという話に直接繋がってるよ
>>533 横レスだけど少しはモナドでググって知識を付けてから質問したらいいと思いました
このおっさん都合の悪いレスは全部無視するから無駄だと思うぞ
Cだったら副作用のある関数を「書こうと思えば書けてしまう」けど, Haskellだったらそんなものはそもそもコンパイルが通らない(から安全) って話じゃないの?
mainに一回だけunsafePerformIOを適用すること それ以外はunsafePerformIOを適用しないこと このルールをコンパイラが保証できるか? 暗黙のルールをこっそりと保証するにはどうすればいいのか
Cに副作用がないとか言ってる奴は、そもそも計算とは何かなんて考えた事もないんだろうな。
そもそも計算とは何なの?
親切に何度もリンク貼ってくれてるのに読んでないんだろうなあ>副作用 この人質問するのはいいけど全然自分で調べようとしないから話が進まないにも程がある
「汚いまま、アホなままで良いからシンプルにしとけ。」 それがマシンパワーの弱かった時代のCとUNIXの哲学だからな。 ところが本物のアホは今やそれがアホげた志向だと気づく事が出来ない。 こういうアホはそのうち今のCOBOLとコボラー並に邪魔ものになるよ。
いや、CとUNIXの汚さは副作用とか以前の問題だし……
>>530 きっちりなんて曖昧でしたね、すいません。
「きっちり分けられる = 関数単位で分けられる」 です。
Haskell のプログラムの基本単位は関数です。
Haskell の言語仕様では関数単位で副作用の有無が定まります。
ステートメント単位とか、命令単位とか、行単位とかではなくて、
関数単位です。
戻り値が IO a 型ではない関数は、絶対に副作用はありません。
(本当は例外があるのですが、話がややこしくなるので今は考えません)
しかし、ほんの少しでも副作用をさせたいのなら、
その関数は IO a 型の値を戻さないといけません。
ほんの少しであっても、「その関数自体が副作用がある」と見なされます。
逆に IO a 型を戻す関数は、副作用があるかどうかは、
実はその関数の定義(中身)を見なければ明らかにはなりません。
ですが、この関数は中に副作用がある処理を含めることが「可能」なので、
IO a 型を戻す関数を内部に含む関数も IO b 型の値を戻すと決められています。
これらは言語仕様です。
プログラマが注意してそのように書くとこで安全性が保たれる、
というレベルの話ではなく、そうしなければコンパイルできないというレベルです。
(
>>537 )
コンパイラは関数の戻り値の型によって、
副作用が絶対に無い関数か、副作用がある可能性がある関数かを見分けます。
そして、ここが大事ですが、プログラマもコンパイルが通るように、
副作用がある関数か、副作用がない関数かをしっかり意識して分けます。
(初心者にとっては、分けざるを得ないという認識でしょうか)
>>530 C言語でも分けられると言いますが、実際のところ、
Haskellのようにしっかり分けるCプログラマはまずいないでしょう。
実行効率やプログラムソースの読みやすさなど、理由はいくつかあります。
やろうと思えば分けられる言語と、分けることが前提の言語では全く違うと思います。
この辺りは、C vs C++ におけるオブジェクト指向と似てるかも知れません。
C vs C++は酷かった CでOOPできないと主張するために、OOPの必須条件が次々と追加されたよね
haskellでは副作用がある部分とない部分を区別して書くことができます じゃなくて haskellでは副作用がある部分とない部分を区別しないと書けません だろ できることじゃなくてできないことに意味がある カプセル化みたいなもん
Haskellは全部副作用ありで書くことはできるんじゃない
コンパイラはそれを許してくれる 周囲の人間の方が厳しい
いや、普通に規格違反だから。拡張使えば書けるけど、Haskellの仕様としては無理。 コンパイラも標準ではそんな書き方認めてないだろ
それでHaskellに於ける副作用とは何なんですか。誰がどういう基準で それを副作用と考えるのですか。
型を全部IO xとかで定義しなおしていけばできるんじゃない?w ひどくメンドクサイことになると思うがw
便乗質問というか教えてほしいんだけど (文法うろ覚えで間違ってるだろうけどふいんきを読み取ってほしい) unMaybe :: Maybe Int -> Int unMaybe Just num = num unMaybe Nothing = 0 みたいな感じで unIO :: IO Int -> Int とかできないの ? できちゃうと副作用の分離が壊れちゃうような気がするんだけど..... 多分、モナドと副作用とIOをごっちゃにしてるんだと思うんだけど、 あと、上で出てきた関数単位では分離出来ているとかそういう話が 理解できてないんだと思うんだけど、 ご教授お願いします。
unsafe〜 を risky〜 に替えよう(提案)
>>553 unsafePerformIOを使えばできる
が、これは通常使用されるべきものではない
558 :
デフォルトの名無しさん :2013/03/05(火) 18:46:22.28
Haskellは参照透過だというのは納得している。 すべてを数学的な関数で表現しているという意味で。 だけど、Haskellには副作用がない・・とする主張は詭弁だと思う。 Haskellに副作用がないといえるなら、C言語もある意味で副作用ないといえると思う。 実際に動作する前までは・・。 DanoMoiの説明を見たときは、ケムにまかれたという感想でもなくて、単に「は?」だった。
559 :
デフォルトの名無しさん :2013/03/05(火) 18:58:39.16
なにか高級な機構を「けむに巻くかのように」説明するかと思えば・・。 副作用の定義を慎重に狭く決めた上、C言語とHaskellの間の、 解釈から実行に至るまでの処理の違いを大げさに主張しただけ。 Haskellの処理と実行の間に、仮想の?プロセスを挟み込んで そのプロセスをHaskellではないとみなすことで、 副作用とやらについて、やっとC言語と差別化できる。 まあ、偉そうなハスケラーには反感を持っていたので 最初から同意するつもりなかったけどね。
わけわかめ
>>535 モナド何読んでもわからないという話から始まっているんだこのスレッド。
定期的に恨みつらみを述べてスレを埋めるお仕事乙です
なぜHaskellとCが同じになるのかさっぱりわからん
>>558 Cは問題ないが、クラスとコンストラクタがある言語が問題だ
static変数を初期化する段階ですでに副作用がある
そういう実行前の副作用をなくしたことは評価されるべき
>>559 何を見ても偉そうに感じる人生なんて想像できない
もっと教えてください!
>>559 もうちょい頭良かったら理解できたのにね
まあその日本語力からして無理か
Cプログラマを下に見ているのは真のLisperぐらいだと思っていたが。 関数型プログラミングの流行で浅はかなHaskellerが増えたんだな。
Cプログラマじゃなくて このおっさんがバカだなって話だけどな
ごめん、別スレでこのおっさんにそんなだからHaskellerに相手されないんだみたいなこと言ったの俺かもしれない。
>>567 Cプログラマに失礼だろ、Cでガリガリプログラム組むようなやつは
Cの問題点もきっちり理解してるし
Haskellみたいなやり方があることも理解してる
>>569 おまえか
おかげでここ数日アホみたいな質問で埋まってウンザリしたわ
長文で我慢強く答えてた人は天使だと思った
いやHaskellをそれなりぐらいには理解してるCエキスパートって、まだそんなに多くないだろ
Haskellのやり方が理解できないとか、Cのエキスパート以前にプログラマとしてダメダメやん
>>573 純粋関数型なのに、どうやって入出力を実現するの? というのが疑問、ってぐらいが普通だと思うけど。
まだそんなにはHaskellは普及してない。
上の方にも副作用を分離してるって書いてあるだろ 分離できる(それを静的にチェックできる)だけで副作用はあるよ
>>575 C言語のエキスパートなら、
関数型的なコードと入出力部分のコードを分離してみるなんて普通に試してみたりするもんだ
C等命令型言語には副作用があって、Haskellには副作用はないと主張する立場から、 それなりに答えたのは、DanoMoiの例くらいだと思うよ。 他の「Haskellには副作用は存在しない」教信者は、「お前は理解してない」と言い張るのみだ。 なお、「Haskellには副作用は存在しない」教信者とHaskell信者は一致しない。
このスレのほとんどの奴は副作用が無いんじゃなくて副作用を分離してるって言ってるだろw
恐らく、Haskellを純粋関数型言語である ということくらいしか知らない多くの他言語プログラマにとっては、 「Haskell = 副作用が無い」という認識なのだと思います。 それくらい、他言語プログラマにとって Haskell はまだまだ謎な言語で、 関わりの無い言語だと言うことなのでしょう。 もし、他言語プログラマにもHaskellに興味を持ってほしいと思っているのなら、 Haskell プログラマがもっと増えるといいなと思っているのなら、 根気よく丁寧に説明していくしか無いと思います。 そんなのはどうでもいい、という事なのでしたら、 せめて説明している人の邪魔だけはしないであげてほしいです。 勘違いの指摘は大歓迎だと思いますが。
あんた偉いよ どうでも良いとは思わんけど、ここ数日の質問者クラスのアホだと教える気なくすわ
べつに丁寧に教えなくても ヒントを少し書いてはい論破でいいんだよ 難しく考えすぎ
こんなこともできるんだって興味持って貰えるような GUIアプリとかゲームとかクライアントサーバ的なものとか作って世に出してかないと 関数型の(精神的な)敷居は高すぎる
フロントエンドは.NETに頼るとして、Haskellをバックエンドとして使えないかな・・ と思っていますが・・。 シミュレーションゲーム作ろうとして挫折しているけど、思考部などをHaskellで作りたい。 Haskellに慣れるための練習として、パズル解答ソフト作成中です。
みんなHaskellでどんなアプリ作ってるの?
UIは入出力しかないしネットは文字列しかない 消去法でゲームが正解
587 :
デフォルトの名無しさん :2013/03/05(火) 21:55:20.69
>>475 >>532 >Cコンパイラは次の関数ポインタを受け取る関数
>int twice(int (*f)(int), int x) {
> return f(f(x));
>}
>が副作用があるか無いかを、どうやって知れば良いの?
>渡される関数ポインタfがどんなものか分からないのに。
twiceが副作用のない関数であることは、"int twice"から自明だ。
そして*fで指されたfが本当にint->intであることをチェックしたいなら
twice呼び出し側の"int (*f)(int)"パラメータの素姓を辿っていけばよい。
それだけのことだ。
>それとも、関数ポインタが渡されるときは、常に副作用があると考えるの?
そんなことはしない。
IOモナドのおかげで泥臭いIOがそれなりに安全に書ける Haskell強力な手続き型言語だと思った
>>587 "int twice"から自明であると思った根拠を述べてください
>>587 int twiceから自明ってどういうこと?
int twice(int (*f)(int), int x){
static int n = 10;
return n = f(n);
}
副作用はvoidを返す関数のことじゃない
中でグローバル変数を更新してるかもしれないし、 Cでそれを型から確認する方法はないな。 GCCなら __attribute__ ((pure)); と書いて、プログラマの責任でコンパイラに対して 保証してやることはできるが。
>>587 > twiceが副作用のない関数であることは、"int twice"から自明だ。
え?
int twice(int (*f)(int), int x) {
static int n = 0;
n += f(f(x));
printf("%d\n", n);
return n;
}
だからバカなんだから相手すんなよ まだ続けんのかよ
unsafePerformIOを自粛することが自明であるのと同じだと思うよ voidではない関数の中では副作用を自粛する
>>595 int main(int argc, char* argv[]) {
}
副作用を自重してくださいね!
597 :
デフォルトの名無しさん :2013/03/05(火) 22:23:46.83
>>593 なんでそんなややこしい例をだすんだよw
int twice(int (*f)(int), int x) {
printf("%d\x", x);
return x;
}
でいいんだろ
int printf(const char*, ...) なんか副作用ない気がしてきた
>>595 unsafePerformIOはgotoレベルだからまた別だと思うの
600 :
デフォルトの名無しさん :2013/03/05(火) 22:30:55.57
>>598 ようやく分かってきたか
それは副作用ないと判断すればいいんだよ
ほんとに分かってる?
>>598 ライブラリを作り直す必要があるね
Haskellはライブラリのついでに言語も作り直したのだ
printf系は副作用そのものを目的にしていると思うけど。
C++でさえ、<stdio.h>等を無かったことにする風潮だからな
>>597 static変数が使われたら自説が破綻するからややこしいということにしてstatic変数を消した
OpenGL の GLUT で簡易GUI作ったけど、C言語で書いた場合より複雑になった もうダメだわ
>>605 何々をやってみたがダメだったとだけ言われても、
それがどうしたとしか言いようがない。
Haskellは使えんと言いたいのか?
それとも、何か質問や議論したいことがあるのか?
少なくとも、GUIデザインする場合、「俺には」使えん
だから、それがどうした そんなもんツイッターにでも書いておけよ
議題:Callbackを簡潔に書くには?
それをクロージャがある言語に訊くか?馬鹿なのか?
GUIは言語あんまり関係無い RADツール次第
>>611 はCallbackが簡潔に書ければGUIは簡単に書ける
と言っているように聞こえる。
そんな馬鹿なと言いたい。
GLUTは分からんというか、分かった上で複雑すぎる気がする
>>616 Callbackするフレームワーク
イベントキューを含めた話で
GLUTは低水準でもフレームやキューやコールバックを使いまくってるから困る
>>620 >>それをクロージャがある言語に訊くか?馬鹿なのか?
この発言が出るくらいだから理解しているはず
今日も微妙にかみあってないな、このスレ
一緒にからみあおうぜ!
外部APIなしでプラットフォームに付属してるモノだけでOpenGLのGLUTのメインウィンドウが表示されたときは少し感動したが
>>621 それはお前の思い込みだ。
お前は会社や学校でもそうやって後足しして
仲間を苛つかせてないか?
627 :
デフォルトの名無しさん :2013/03/06(水) 08:03:03.67
>>589 言うまでもないと思うが聞かれたから言うよ
"int twice"と書かれているからだよ
ほんとにそうかはtwiceのbody部を見ればよい
xがintでfがint->intなのだし他に何もないからほんとだとわかる
fがほんとにint->intかは...(同じことの繰返し)
>>627 へー、じゃあコンパイラでチェックできますよね?
>>593 のコードに警告かエラーを出すコンパイラ教えてください!
>ほんとにそうかはtwiceのbody部を見ればよい バーカバーカ
630 :
デフォルトの名無しさん :2013/03/06(水) 09:07:50.97
631 :
デフォルトの名無しさん :2013/03/06(水) 09:09:45.69
副作用とは何ですか?
100歩譲ってint twiceの副作用と渡された関数の副作用を分けて考えてるとしても、「見れば分かる」ってすごいなw
いや、見てわからなきゃどうしろと?
最終的には見なきゃ分からないのが問題
638 :
デフォルトの名無しさん :2013/03/06(水) 09:59:36.88
モナドの話はどうなったのでしょうか? IOや副作用の話ばっかりになったようなのですが。
消えた
640 :
デフォルトの名無しさん :2013/03/06(水) 10:07:09.97
>>637 見るのがコンパイラでも?
Haskellは見なくても分かるの?
641 :
デフォルトの名無しさん :2013/03/06(水) 10:10:56.20
>>640 どのコンパイラの話をしているの?
Haskellは文法上書けないから見るまでもない
643 :
デフォルトの名無しさん :2013/03/06(水) 10:26:49.28
>文法上書けないから 書いたらどうなるの?
>>643 だから書くための文法がないんだってば
書きたくても書けない
「書いたら」なんてあり得ない
書いた場合と書かなかった場合の両者を想定するのは動的型の発想 静的型は片方をあり得ないと想定し複雑度を下げようとするんだよな
646 :
デフォルトの名無しさん :2013/03/06(水) 10:40:02.89
>>644 書けないのはコンパイラが文法の観点から 見 て いるからでしょ。
640の言うのも、単なる文法チェックでは済まないだろうけど機械が
見 れ ば分かるので、その意味では同じじゃないのと言ってるんじゃないの?
「文法上書けない」ってすごいな どんな凄い文法なんだろう
>>646 そりゃ当然どこかで副作用の無いことを保証しなくちゃいけないし、その保証のプロセスを「見る」というならそうかもしれない
でも、その保証が文法レベルで存在することって重要なことじゃない?
そして、それを「見て」くれるCコンパイラってどれのことを言ってるの?って聞いてるのに答えてくれないんだよ…
若干話はそれるが、Haskellが関数に副作用がないのを保証したいのはなんでなの?
副作用がないのを保証するというより、参照透明性を保証する
副作用を認めると 引数や戻り値の型とは違う型のデータを、どこかに隠された変数に入れたり 例外として投げたりできるから
x = yの時f x = f yが言えないと等式推論が役に立たないからプログラム運算関連の人の飯の種が減るという大変困ったことになる
そりゃ大変だ
>>651 計算している間に音が出るというようなことには
副作用という観点からはあまり関心がないという
ことになるが。
他の関数型言語はHaskellほど縛りがきつくないのもあるんだろ? 逆に言うとHaskellは副作用(参照透明性の確保?)に対して厳格すぎるから モナドとかいう難しいものを導入しなければならなかった、と理解してるんだけどあってるかな? そこまで厳格に参照透明性にこだわるメリットってなに?
そういう宗教
中途半端になると弱い 現に、オセロでは中央より隅の方が強い
C++等でテスタビリティとモジュラリティの為にconst付けまくるみたいなスタイルは 手続き型言語における参照透過性のメリットの一例 意味論で考えると参照透過な実装はそうでないものより事前事後条件が簡単っていうのがある つまり意味論的な解析を利用するような静的検査がやりやすい こういうのがデフォルトで使えるっていうのは「タイプは基本的に遅いけどconstは一瞬で打てるようになった」みたいな人にとっては青い芝生だわな
つまりバグの出にくいプログラミングスタイルを言語で強制するって事?
少し自分の頭を使えよ 参照透過性のメリット理解できてないとか プログラマとして普通に三流だぞ
テストしやすい、ということもある。 入力以外の、たとえばグローバル変数みたいなものに影響されないから。
どんな状況でも常に同じ結果を返す関数なら、 結果をキャッシュしたりすることもできるんだよね。
関数の実行順序を考慮する必要が無くなるってことは並列処理にも向いてる
マルチスレッド処理でロックの必要が無くなる
>>660 プログラマを買いかぶってはいけない。プログラマの99%は三流以下だよ。
IOネタはもうずっと年中タイムリー
>>654 beep()で考えると、一回beep()が実行されると、一度音が鳴る。
続けて3回実行されれば、三度鳴る。というように積み重ねられる
ことによって、コンピュータの挙動が変化する。beep()自体は
変化がなくても、コンピュータ全体としては変化してしまう。
これが一般的な副作用。参照透過性の議論は計算モデル内部に
限定しての話でこれは勿論副作用論議の重要な部分だがすべて
ではない。
haskellを使う理由を教えてください 当方PHPしかできません
beep() がグローバル変数を書き換えてしまう事が無いことを保証できないしね
659への返答は「そうだよ」じゃ駄目なんかな まあでも,なんでわざわざ関数型言語を使うのか,というのは別の話のしかたもあるかも lyahとか「なぜ関数プログラミングは重要か」あたりの文章を読んでみるとか
いやっはー
675 :
デフォルトの名無しさん :2013/03/06(水) 16:20:27.75
オレも質問。 ・モナドにはIO、State、List、Exception、Maybe等々いまでも多数あるが、 これで終わりじゃないよね?まだこれからいろんなモナドが現れるんだよね? アドホックに。 ・それらは皆モナド則を満たすわけだが、このモナド則って結局何を言ってる んだっけ?
>>675 モナド則はモナドのモジュールを作る側が気をつけることで、
おまえみたいに誰かがモナドを作ってくれると思ってる奴は気にする必要が無い
参照透過性 参照透明性 訳語として、どっちが普及してるの? 僕は参照透明性です!
678 :
デフォルトの名無しさん :2013/03/06(水) 18:38:20.92
もうだめかもねこのスレ はぁ
おっさんが居なくなれば普通に平常運転だと思うけど
>>630 とか都合悪くなったら話逸らしてるし
無知を装った荒らしか無知な荒らしだと思います><
おっさんが居なくなって別の奴が別の話を始める事象と 同一人物が話を逸らす事象は見分けがつかない
Haskellでメモ化をしたいのだけれど どうやるのがいいと思う?
>>683 HaskellでPrologインタプリタを書く。
685 :
デフォルトの名無しさん :2013/03/06(水) 21:03:09.41
>>679 など
このスレはなんかデリケートなオタクが多いようだな
また来たのかおっさん
ナイーブだな
いまだに「敷居が高い」に突っ込み入れる阿呆居るんだな
Haskellスレらしくていいじゃないか
692 :
デフォルトの名無しさん :2013/03/07(木) 09:40:40.92
関数型言語は那珂太郎の詩のようなところがあるから。 ..の..の..の..の..の..の..の..の..
Haskellを汎用CPUで動かすの効率どうなの? そういう最適化の準備あるなら専用プロセッサあった方がいいんじゃないの?
GHCについて言うなら、基本設計からstock hardwareで最適に設計されてるので、 あまりそういう改善の余地は少ない。
(´・ω`・)そうなんだー
697 :
デフォルトの名無しさん :2013/03/07(木) 17:45:45.03
679が泣いたりするからつまらんくなったな なんか言えよおまえら
ソフトウェアトランザクショナルメモリの欠点について教えて
699 :
デフォルトの名無しさん :2013/03/07(木) 18:46:50.69
口に出すと読みにくい
遅い
(´・ω`・)そうなんだー
なんだその顔は!ふざけてんのか!
\|/ /⌒ヽ | ゜Θ゜) そうなんだー | ∵ つ | ∵ | \_/
おっさんがいないと、何をしても心から楽しめないの、、、
これってもしかして……恋?
ξ ゞシヾ" ヽ ,,,....,,,、、...,,,....,, ! 彡 ヽ::: ..i'´. ヾ'''、、、,,, シ 彡 ,j::: ..,/ヾ, ヽ !シ ,,彡 :シ ,;'''' ヾ ,___ ヽ j ,-‐-、 i ッ三ミ:;j i、' j-‐ `, , ‐'' = ) ヽ: し { !⌒- ヽ! j ‐-‐'j ヽ、...' ' .,_//, !;:: ヾ丶`-' ! ! {__,__,!' -‐' ヾ ノ::: ,ヾ ' 、 ,' ....,) :: ヽ ノ:::::: _...-‐‐'''´ ::: ´::( _... ´ ヽ /::::::: :: ! .... -‐´ ヽ /::::: __,....,,-‐-、 ::::. ヽ !......:-‐ー、 ,,,,,,;;;ヽ __ ...-‐、 :: `ヽ-、___,--/'´ ,、 , `ヽ、 !:::,´´´´´:::::`"""´:::::::::::::::;;;;;;;;ヽ、 ;:: ヽ-‐' ! ./ iヽ
709 :
708 :2013/03/09(土) 05:49:42.46
誤爆しました・・・申し訳ありません
"nを法とする剰余類環"の型って作れないのかなあ… "Mod 12" 自体が型になってるようなの( C++風に書くと"Mod<12>" ) でも12の部分は型名じゃなくちゃいけないんだから無理か
TH を使えばいけるかも あるいは data Zero data Succ a 的なのでゴニョゴニョ
>>710 GHC7.6ならDataKinds拡張で12を型として使える
でも型レベルの加減乗除はまだ実装されてないのでまともに使えるかは知らん
{-# LANGUAGE DataKinds, KindSignatures, ScopedTypeVariables #-}
import GHC.TypeLits
newtype Residue (n :: Nat) = Residue Int {- invariant: 0<=x<n -}
deriving (Eq, Ord)
-- smart constructor
residue :: forall n. (SingI n) => Int -> Residue n
residue a = Residue $ mod a $ fromIntegral n
where
n = fromSing (sing :: Sing n)
instance Show (Residue n) where
showsPrec p (Residue x) = showsPrec p x
instance SingI n => Num (Residue n) where
Residue x + Residue y = residue $ x + y
Residue x - Residue y = residue $ x - y
Residue x * Residue y = residue $ x * y
signum (Residue 0) = 0
signum _ = 1
abs x = x
fromInteger = residue . fromInteger
main = do
print (3 + 4 :: Residue 2)
print (3 + 4 :: Residue 3)
print (3 + 4 :: Residue 4)
714 :
デフォルトの名無しさん :2013/03/09(土) 11:21:45.67
質問です ファイルをインポートしようとしたのですがエラーがこのようにでました。 Could not find module `Dates' Use -v to see a list of the files searched for. Failed, modules loaded: none. Dates.hsでは module( --- data や 関数 ) where のように外部からアクセス出きるようにして、 インポート側はimport Datesを最初の行にいれています。何がいけないのでしょうか?
>>714 Dates.hsを置いてるディレクトリと、GHCを実行してるディレクトリは同じになってる?
もし違うなら、-iとかを渡さないといけない
716 :
デフォルトの名無しさん :2013/03/09(土) 14:22:34.44
同じディレクトリに移動してやったら出来ました。 ありがとうございます。
みんなHaskellのことならなんでも知ってるな
自分で言語を作るならどういう選択肢があるかを知ってる Haskellの作者がどれを選んだかは知らないので後で調べる 他人が何をしたか調べる時間よりも、自分ならどうするかを考える時間の方が長い
サーベイをさぼって「もうOlegがやってた」とかで数日無駄にするとかよくあった
その代わり速読(笑)で数日短縮できるんじゃね Olegが何を言いたいのか読む前から知ってるんだから
以下をGHCiにロードすると' Parse error in pattern: n + 1'というエラーがでます HUGでは通るそうなのですが何が悪いのでしょうか drop2 :: Int -> [a] -> [a] drop2 0 xs = xs drop2 (n + 1) [] = [] drop2 (n + 1) (_:xs) = drop2 n xs
>>721 (n+k)パターンはデフォルトでは使えなくなったような気がする。
あきらメロン
NPlusKPatterns を指定
{-# LANGUAGE NPlusKPatterns #-} drop2 :: Int -> [a]->[a] drop2 0 xs = xs drop2 n [] = [] drop2 n (_:xs) = drop2 (n-1) xs
725 :
721 :2013/03/10(日) 18:29:24.02
そうだったんですか オプションが必要になるならあきらめマスクメロン
関数内で関数定義するとテストできないよね? みんなどうしてるの?
テストが要るような関数をローカル定義にしないという解決法
Javaだとリフレクション使ってprivateメソッドもテスト可能だが Haskellの関数定義にはそのような抜け穴が存在しないのではないか
テストが要るほどに非自明な関数はトップレベルに定義すればよい
テストが困難になるのは使い道が無数にある場合だから 一回ぐらいしか使わないローカル関数のテストは難しくない
ghc-modでローカル定義拾うのあるし GHCにも穴はあるんだよ多分
>>726 関数内で関数定義する場合に、
どういうテストが不可能だと言っているの?
>>731 ローカル変数は、名前とソースの位置が同じだが値が異なる変数を何個も定義できるよ
トップレベルの変数を一個拾うのとは全然違う
関数内関数までテストしたくないです 理由は、関数内関数には外部から見える仕様が存在しないからです
大元の関数をテストすればいいんじゃないの?
内部関数というのは、他の言語で言えばコードブロックみたいなものだからね コードブロックの一つ一つまでテストする必要はないし、テストの必要があるほど大きなブロックなら独立させればいい
Smalltalkだとメソッド内ブロック使わないと何もできない その後、OOPにブロックは不要という考え方が定着し OOPと関数型は完全に分裂した
>>737 最近のOO言語はやっぱりクロージャが必要って流れになってるよ。JavaもC++も。
三大やっぱり必要 テスト public lambda
リフレクションかな haskell-src-extsとか使ってローカル定義を参照できるようなツールがあればいける
>>737 その場合、SmalltalkはOOPと関数型のどっちの所属なんだ?w
今でもSmalltalkはブロックがないと何もできないわけだが。
特定のクラスに所属しないユニバーサルな関数はOOPとは相性が悪い プリミティブ型がOOPと相性が悪いのと同じ理屈
>>743 そんなことないよ。Javaとは相性悪いけど、OO言語だからじゃなくて、Javaが糞だから。
>>743 SmalltalkのクロージャーはSmalltalkと相性悪いの?
Smalltalkってクロージャーがないと条件分岐すらできないんだけど?
HaskellとSmalltalk、唯一の共通点はモヒカンっぷり
HaskellとSmalltalkはモヒカンの中でも最弱・・・ 本物のモヒカンは静的型とGUIを否定する
いまだにモヒカンの定義が良く分からんのだよなあ
良く分からないものの擬人化 モヒカンの陰謀か何かで、分かるはずのものが分からなくなる
>>745 クロージャーもクラスにできるんだけど、プリミティブなくせに抽象度が違うので、これをクラスとして扱いつづけるといろいろおかしくなる
>>750 BlockClosureクラスだと何がいろいろおかしくなるの?
SmalltalkってBlockClosureクラスがないと条件分岐すらできないんだけど?
もしかしてJavaの.classファイルがものすごい数になるのを心配してるんじゃないか
>>743 どう相性が悪いの?
カプセル化する必要のない関数はクラスに所属させる必然性はないけど
それがOOPの妨げになる理由は?
それにnamespaceとかあるよね?
そのレスただ言いたかっただけに見えるよ
クロージャをクラスにしても問題ないだろう 単にJavaみたいに1クロージャを1クラスに対応させるのが腐れなだけ クロージャをリテラルにしてどのクロージャも同じクラスになれば問題なし
ユニバーサルな関数やクロージャがOOPと相性悪いとか頭悪すぎだろw Javaしか(もしくはJavaすら)知らないんだろうね
「いろいろおかしくなる」ってなかなか趣深いフレーズだな
>>753-754 ・ OOPにおけるクロージャは飛び先が隠ぺいされる goto
・ クラスの遠隔に設置される場合は、名前がないのでクロージャのセマンティクスが明確に消失する (\x -> \x +1)は加算? 曜日のシフト?
・ (\x -> \x +1) と (\y -> \y +1) をそれぞれクロージャクラスのオブジェクトにしたときの同値判定
・ (\x -> \x + 1) 1 のとき、 アプライが必要になってクラス表現するときとプリミティブのときでセマンティクスが崩れる ネストしたときのリフト
・ クロージャのオブジェクト生成がクラスのオブジェクト生成と同期しない
・ クロージャの生存期間がクロージャだけを見ても分からない
頼むからちゃんとした日本語で書いてくれ
これは早口言葉のようなもので 日本語の読み書きの問題ではない気がする
>>757 何が言いたいのかよくわからんから最大限エスパーして答えるけど、ほとんどOOPじゃなくてクロージャ自体の話に見える
例えばそれぞれlispのクロージャだと何故問題にならないの?
>・ OOPにおけるクロージャは飛び先が隠ぺいされる goto
そう言いたければ好きにすればいいけど、で?OOPとの関係も不明
>・ クラスの遠隔に設置される場合は、名前がないのでクロージャのセマンティクスが明確に消失する (\x -> \x +1)は加算? 曜日のシフト?
OOPと無関係
>・ (\x -> \x +1) と (\y -> \y +1) をそれぞれクロージャクラスのオブジェクトにしたときの同値判定
なぜ同値判定が必要なの?OOPとの関係も不明
>・ (\x -> \x + 1) 1 のとき、 アプライが必要になってクラス表現するときとプリミティブのときでセマンティクスが崩れる ネストしたときのリフト
何が言いたいのかわからん(何をクラス表現するのか、セマンティクスがどう崩れるのか、何をネストしてリフトするのか)
>・ クロージャのオブジェクト生成がクラスのオブジェクト生成と同期しない
「クロージャのオブジェクト(生成)」の意味がわからん。生成が同期しないことによる弊害も書かれてない
>・ クロージャの生存期間がクロージャだけを見ても分からない
OOPと無関係
俺も頑張って
>>757 エスパーしたわ。
>>760 が答えてるけどエスパーした時間が勿体無いので投下。
・ OOPにおけるクロージャは飛び先が隠ぺいされる goto
→OOPでもオブザーバーパターン使うと飛び先が隠ぺいされる。
・ クラスの遠隔に設置される場合は、名前がないのでクロージャのセマンティクスが明確に消失する (\x -> \x +1)は加算? 曜日のシフト?
→(\x -> x.addNum(1))や(\x -> x.addDay(1))としたらいい。
・ (\x -> \x +1) と (\y -> \y +1) をそれぞれクロージャクラスのオブジェクトにしたときの同値判定
→参照の同値性を実装している言語はあるけど、それだけだとOOPとして困る状況ってある?あと「振る舞い同値性」や「α同値性」でググれ。
・ (\x -> \x + 1) 1 のとき、 アプライが必要になってクラス表現するときとプリミティブのときでセマンティクスが崩れる ネストしたときのリフト
→これは意味不明。
・ クロージャのオブジェクト生成がクラスのオブジェクト生成と同期しない
→「同期しない」が意味不明。newという構文を使わないから駄目だという話か?OOPでファクトリ使うときも使用側にnew無いけど。
・ クロージャの生存期間がクロージャだけを見ても分からない
→OOPもクラス定義だけ見ていては分からない。インスタンスへの参照がどこで消えるか注意深く追う必要がある。
なんだこの最強エスパー決定戦は
763 :
デフォルトの名無しさん :2013/03/14(木) 02:28:30.07
>>760 ・ クロージャが特にOOPで飛び先が隠ぺいされる goto になる理由は、個性のないクロージャがオブジェクトに抽象化されてオブジェクト自身が持ちまわされるから
・ クラスの遠隔に設置される場合に名前がないのでクロージャのセマンティクスが明確に消失するという問題は、裏を返せば、クラスの遠隔に設置される場合と同じリテラスなのにセマンティクスが変わってしまうということ
・ クロージャのオブジェクトとしての同値判定は、クロージャをクラスにしなければOOPとは無関係
・ プリミティブの場合は (\x -> \x + 1)1 でOKだが、クラスにするとただ並べるだけではダメで クロージャのオブジェクトに1を適用するというステップが間に入り、セマンティクスが異なる
・ 他のクラスのオブジェクトと生成が同期しないことによる弊害はリソースを保持するコストの推定が難しくなること
・ クロージャの生存期間がクロージャだけを見ても分からない理由は、OOPではクラスのオブジェクトの生存期間の明示が難しいから
764 :
デフォルトの名無しさん :2013/03/14(木) 02:45:02.81
>>761 OOPでもオブザーバーパターン使うと飛び先が隠ぺいされる。
→ここでの「隠ぺい」はコードを追って保守するのが難しいという意味
(\x -> x.addNum(1))や(\x -> x.addDay(1))としたらいい。
→このように、クロージャを利用するクラスの近くか遠くかにより必要となる記述が異なるので、ユニバーサルなクロージャとOOPは相性が悪い
参照の同値性を実装している言語はあるけど、それだけだとOOPとして困る状況ってある?
→メソッドの出力またはフィールドの値がクロージャのクラスを単体テストする場合
これは意味不明。
→「(\x -> \x + 1) 1」 と 「(インスタンス化(\x -> \x + 1)).apply(1)」 は字面が違うでしょ、という意味
「同期しない」が意味不明。
→リソースを消費するクロージャは、代入のときか、代入が予定されるクラスのオブジェクトが生成されたときか、実行されるときか、いつオブジェクト化されるかが問題になる
OOPもクラス定義だけ見ていては分からない。
→当然そのクラスで回されるクロージャはもっと分からない
はすけるスレでこんなこと言うのもなんだが
>>763-764 はOOPまるでわかってないに1票
恥ずかしいことじゃないよ、ここははすけるスレだから
うーん。。。要はケースバイケース、使い分けしてナンボだと思うけど。 わざわざクロージャの悪い使い方を上げて、クロージャ自体を批判しなくとも良いのでは?
>>754 クロージャが問題ならInterpreterパターンを使えば良いよね
いやOOPが分かってないって問題じゃないだろこれw プログラミングがまるで分かってない
こんなに議論ができる人たちが、 プログラミングが分かっていない、状態になるのだとしたら、 OOPもクロージャもなくす方向に向かうほかないのでは。
>>768 確かに、コード一行も書いたこと無い人が本だけ読んで語るとこういうことになるのかもね
>>769 いや分かってないのは一人だけでしょ
稀にこういうどうしようもない馬鹿が表れるのは仕方無い
>>763-764 に足りないのは論理的思考能力じゃね?
まあ論理的思考能力に欠けてるやつがプログラミングできるとは思わんが
>>726 あたりから延々と続いている議論はどんなレベルのプログラマに必要な
ものなのかな。
もし関数型を理解することがこんな議論が分かるようになることを含むのだと
すると、関数型言語を勉強しようとする人はほとんどいなくなってしまうだろう。
バカの妄想にレベルもクソもなかろうもん
×関数型 ○Haskell 頼むから他のまともな関数型言語まで一緒にしないでくれ
>>772 日本語や英語の議論に飽きた人は、ますますプログラミング言語への興味が増すだろう
確かに >>760-
>>764 を読むとHaskell本当に大丈夫か?という気になる。
生兵法は怪我の素
生なんだよね 人が作った物というより生物に似ているから、期待通りに動かないのは当たり前 人間以外の生き物を知ってたらどんなレベルの人でも理解できると思う
また変なやつまで来たし。もうやだこのスレ……
>>763-764 を納得してしまったのは俺だけか?
とくにクロージャがgotoというのは至言
何がどうgotoなのかさっぱり話が見えない
オブザーバーパターンみたいなコールバック使うとOOPでもコード追うの難しいよね っていうことを言ったはずなのに伝わった気がしない
>>781 そうだとしてもOOPと関係ないだろって突っ込まれてるんだが……
お前もズレてるな
言ってることを一文ずつ取り出すと完全に間違ってるとは言えないんだが、全体として整合性が取れてなかったり会話の流れからずれまくってるやつ、俺の近くにも居るわ 何の障害なんだろうか
よいGOTOとしてのクロージャ : ハンドラ関数に渡すクロージャ 悪いGOTOとしてのクロージャ : 制御構造に干渉するクロージャ c = (\(f,xs) -> " and " ++ (f xs)) func [x] = x func (x:xs) = x ++ (c (func, xs))
皆さん次のエスパー課題です
>>787 じゃあgotoの話に絞ると、クロージャを変数に代入した場合は何故同じ問題が起きない?
>>790 クロージャを変数に代入して問題が起きるなら、別のソースコードで定義してあるクラスのオブジェクトのフィールドに代入するともっと問題が起きるよね
>>791 グローバル変数に代入したり、関数からクロージャを返して別のソースコードで利用されるのとどう違う?
えっ、クロージャがオブジェクトに抽象化されて持ちまわされるのが問題って言ってるのに、なんで別のオブジェクトのフィールドに代入する話になってんの?
第二次エスパー大戦
>>792 アクセス可能性(参照性)が違う
クロージャを使うコンポーネントの粒度と、そのコンポーネント自身を使いまわされる度合いが違う
OOP原理主義に走ってオブジェクトに属さないグローバル変数を認めない場合は根本的に違う
>>791 に書いてる「クラス」「オブジェクト」「フィールド」って言葉は全く何の意味も成してないな
「別のソースコード」はまだ分かるがそれこそOOPと何の関係もない
マジでOOPとクロージャの関係にケチ付けたいだけなんだな
最強のスパゲッティ言語 = ラムダ計算
>>795 >>791 グローバル変数に代入したり、関数からクロージャを返して別のソースコードで利用される場合と比べて、別のソースコードで定義してあるクラスのオブジェクトのフィールドに代入する場合にどう問題が大きくなるか聞いてるんだが
なんでラムダがgotoと同じってことになったのか理解できない 関数呼び出しはPCの変更だからgotoと同じって言ってるのと同レベルの屁理屈ってことでFA?
>>796 クラス=クラスの仕様そのもの、ソースコード上で確認できる
オブジェクト=クラスをインスタンス化してメモリ上に存在している実体
フィールド=クラス上で定義され、オブジェクトに属し、明示的にアクセスを制限されるプロパティ、変数
「別のソースコード」でかつOOPだと困る理由は、OOPでは別クラスのフィールドの定義だけを一ヶ所に寄せ集めるコーディングができず、場合によってはアクセスを制限されるから
>>801 かつ、それがOOPとどう関係するのかも分からない状態
追跡する必要があるってことは副作用のある名前のない関数について話してるんだよねこの人 それはいいとしてそれをHaskellスレで披露して暴れてるのは何でなん
こいつの噛み合わないレスを見てると、なんか恐怖を感じる……
>>800 ・OOPでは、個性のないクロージャがオブジェクトに抽象化されてオブジェクト自身が持ちまわされるが、グローバル変数に代入する場合にはそれが難しい
・クラスの遠隔に設置される場合は名前がないのでクロージャのセマンティクスが明確に消失するが、クラスの内部にあればクラスそのものがクロージャのセマンティクスを修飾する
・クロージャのオブジェクト生成がクラスのオブジェクト生成と同期しない
・クロージャの生存期間がクロージャだけを見ても分からない
次回 「人外っているんだなって」
やっと翻訳できる人が表れたかと思ったらご本人様だったか
噛み砕いて書いたと思いきや繰り返して同じこと書いてるだけだった
>>801 GOTOしての関数呼び出しと、GOTOとしてのλ式の違いは、GOTOが制御を奪えるかどうか
GOTOとしてのλ式はフローや繰り返しの最中で制御を横取りできてしまう
多分この人、プログラミングじゃなくて文学とかの方が向いてる
せめて具体例とかつけてくれよ
>>806 >・OOPでは、個性のないクロージャがオブジェクトに抽象化されてオブジェクト自身が持ちまわされるが、グローバル変数に代入する場合にはそれが難しい
いやいやオブジェクト云々は問題が起きる理由の一つでしょ?それを否定してどうするんだ
そうじゃなくて、クロージャが(悪い?)gotoになる問題が、
(プリミティブな)クロージャをグローバル変数に代入したり、関数からクロージャを返して別のソースコードで利用される場合には発生しなくて、
別のソースコードで定義してあるクラスのオブジェクトのフィールドに代入する場合には発生する理由を聞きたいんだけど
>>812 え・・・国語も出来ないのに
>メソッドの出力またはフィールドの値がクロージャのクラスを単体テストする場合
メソッドの出力かフィールドの値は自発的に単体テストを施行しちゃうAIらしい
これ間違った方向に勉強しちゃったこないだのおっさんじゃね?
おっさん得意の実例出さないで抽象化した言葉を並べる続けることで 反論を跳ね返すオナニー用のマジックミラーやで 実際のところ何もわかってないから相手するだけ無駄
しかしこんだけ絶妙に意味不明な文章を羅列できるのって才能っちゃ才能だよな モスバーガーの食い方のアレを思い出すわ
誰かstaticおじさんを連れてきてくれ こいつと話し合いができるのは彼しかいない
>>810 制御を横取りするのはschemeのcall/ccとかでは?
クロージャが制御を横取りする具体例を出してよ
まさかただの高階関数を指して制御を横取りとか言ってないですよね
母親がホームで自転車で痴漢されたやつみたいになってきたな
↑ご本人様
好きって絶妙な意味不明さがってことだぞw
>>825 それ呼び出し元に戻ってくるじゃん
goto?
限定継続って単語出せば煙に巻けると思ったんだろうねw
>>820 ○最単純例 (\f -> exitSuccess) (print "hai")
○よくやる悪い例(
>>786 )
c = (\(f,xs) -> " and " ++ (f xs))
func [x] = x
func (x:xs) = x ++ (c (func, xs))
○推奨される例 ハンドラの例外処理にクロージャを渡す
「制御を奪う」とかいう話を、よりによってHaskellスレで聞けるなんて、ムネアツだぜ!
話の腰を折ってすまんが 「OOPとクロージャは相性悪い」 なんて言ってる人は 「FPと高階関数は相性悪い」 と言ってるのにほぼ等しいことを自覚してくれ。
あと、JavaをOOPLだと思うのはやめてくれ。 あれはOOPLではない。OO用語を使った命令型言語だ。
>>831 クロージャが元凶だってことだけはわかった。
元凶はJavaだけでOOP騙っちゃう例のあの人でしょw
こいつみたいな知ってる専門用語を適当に並び立てるんだけど、全く意味が通ってないやつ居るなー 一般人や初心者にはなんか頭良さそうって思われてるけど、同じ分野の人からは馬鹿にされてるタイプ
批判は得意な人ばかりのスレですね 少しは建設的なことはいえないのですか?
プログラム変換について拘るというのなら分かるが、数学的洗練を期待して このスレに来ている人たちは、OOPもクロージャも関係ない。 「プログラミングHaskell」の巻末索引に登場する程度の概念でさらっと やって欲しい。
さすがにクロージャは関係あるんじゃね?
>>832 >OOPLではない。OO用語を使った命令型言語だ。
もしかしてOOPLと命令型言語が相反する概念だと勘違いしてる?
JavaもC++もRubyも、どれも全部「OOPLであり同時に命令型言語」だぞ
>>840 メッセージ送信をメソッド呼び出しだと思ってるでしょ?
ちがうの?
このスレ何だか難しいね!(´^ω^`)
一般人から見たら馬鹿かと思えるような会話を難なくこなせるようでないと 自らHaskell使いを名乗ることなど出来んのだよ
メソッド呼び出しはオブジェクト指向においてメッセージ送信を実現する方法の一つ
はずれ
メソッド呼び出しがメッセージ送信を実現すれば、メッセージ送信は正義 いろいろおかしくなったらメソッド呼び出しは悪 (メッセージ送信は悪ではない)
Haskellは全力で反証不可能を回避する
>>840-842 メッセージ送信かメソッド呼び出しかは、(構造としての)オブジェクトの粒度と独立性の程度の問題
クラスとメソッドがオブジェクトとして閉じていて、送信元オブジェクトとメッセージとレシーバのオブジェクトが独立していると「表現できるか」がが問題
呼び出し元をオブジェクトとして表現して、関数モジュールを呼び出す際の引数をオブジェクトとは独立して存続していると表現すれば機械語も立派なOOPL
ソースコード上の表現だけで判断するなら真にメッセージパッシングしてるのはerlangだけ
言語仕様だけ見た場合のOOPLと命令型言語の決定的な違いは、メソッドやフィールドの隠匿にこそある
>>849 > ソースコード上の表現だけで判断するなら真にメッセージパッシングしてるのはerlangだけ
Smalltalkでもメッセージセレクタは識別子ではなく文字列リテラルなんだが?
SmallTalkはもうおなかいっぱい。
真に並行動作してるErlangから見れば Smalltalkのメッセージパッシングなんてゴミ
OOPとActorモデルの区別ついてますか?
うんこSmalltalkerがErlangに嫉妬してるの?
SmalltalkもErlangもよくわかってない人が泥沼にはまってるように見える
そろそろHaskellの話をだな・・・
レコード型を定義すると全フィールド名がネームスペースを侵食するの何とかならない?
だって関数ですから
やだやだやだっなんとかしてっ
ネームスペースを侵食する、の意味がよく分からん
qualified module import
Haskellのレコード型は諦めろ
863 :
デフォルトの名無しさん :2013/03/16(土) 12:35:18.75
関数takeを作りたいのですが、うまくいきません。 myTake :: Int -> [a] -> [a] myTake num (x:xs) | num < 0 = error"Not Valid" | num == 0 = [] -- Non-Exhastiveになる myTake 0 [] | num == 1 = [x] | num > 0 = [x] ++ myTake (num -1) (xs) | otherwise = error"Not Valid" myTake 2 [] -> Non-Exhastive
空のリストをx:xsパターンマッチで束縛しようとするとダメなんじゃね? take _ [] = []
>>863 myTake 2 [] は myTake num (x:xs) にパターンマッチしていません。
第1引数の 2 は num にパターンマッチしていますが、
第2引数の [] が (x:xs) にパターンターンマッチしていないからです。
マッチするパターンが記述されていないから、Non-Exhastive になります。
Haskell はデフォルトでは、第1引数がパターンマッチすれば、
第2引数以降のパターンマッチ調査は必要になるまでとりあえず棚上する、
という動きはしません。
コンパイルが通るようにするには、
myTake num [] に対する関数定義をちゃんと書く必要があります。
これが一番素直で簡単で根本的な解決です。
ついでながら、先ほどの棚上げ処理をするように明示する方法もあります。
棚上げ処理は正確には反駁不可パターンなどと言い、
棚上げしたいパターンの記述にチルダ文字を前置することで指定します。
myTake num ~(x:xs) = ・・・
ただし、少なくとも今回あなたが書いたプログラムに限れば、
反駁不可パターンをそのまま使うだけではコンパイルが通るというだけで、
根本的な解決にはならない(実行時例外が起きる)ので意味はないですが。
なんか効率悪いな ↓こうでしょ | num > 0 = x : myTake (num -1) xs
これって、フィールド名 x と xs を定義しているけれど名前空間は侵食されてないよね
868 :
デフォルトの名無しさん :2013/03/16(土) 13:31:58.09
出来れば、 nBanme :: [a] -> Int -> a nBanme [] _ = error"カラ" nBanme (x:xs) n | n < 0= error"セロ" | n == 0 = x | n > 0 = nBanme (xs) (n-1) | otherwise = error"ヘン" のように関数ノ名が何個もあるのではなく nBanme :: [a] -> Int -> a nBanme list n | list == [] || n < 0 = error"" | n == 0 && list == (x:xs) = x | n > 0 && list == (x:xs) = nBanme (xs) (n-1) | otherwise = error"Something Wrong" な感じで関数名が一つなのを定義したいです。 反駁不可パターンなどはもうすこし勉強して理解したいとおもいます。
case (n, xs) ofを使う
867は何言ってるんだ
>>868 そんな変なこだわり持って読みにくいコード書くつもりならPGやめたほうがいいと思う
case 式で書けるには書けるんだけど、 プログラミングHaskellの最後の章にあるみたいなプログラムの正しさを確認する時とかに、 等式の集まりからなるパターンのほうが扱いやすい、みたいなのがあるので、 一つの式にすることにこだわるのはあまり良くないと思う。
haskellの並行処理でforkOに対するjoin関数が見当たらないんですが普通どうするんですか? MVarとか使ってforkIO先で書き換えて同期取るんですかね?
なぜHaskellはアクターモデルを採用しなかったのか
>>873 fork した計算の結果が得られるまで待てばいいんだよね。
mergeIO や nmergeIO はなんか使えると思う。
GHC 7.8 でライブラリから取り除かれるから、
代わりに SafeSemaphore パッケージ使えとも書かれているが。
GHCはパッケージ構成コロコロ変え過ぎだろ 開発で使う場合、実質Haskell = GHCなのに何考えてんだ
標準化の過程で階層化が遅れてたんからしょうがないじゃない。 2010 標準は、もうそんなには変わらないと思うけど。 標準化されてないものは、そりゃあもうしょうがないでしょ。
879 :
デフォルトの名無しさん :2013/03/16(土) 22:11:33.58
{-} nth' :: [a] -> Int -> [a] nth' list number = case (list, number) of ([], number < 0)-> error"Invalid Negative" ([], number == 0)-> error"Index Too Large" ((x:xs), number > 0)-> [x] ++ nth' xs (number - 1) _-> error"Something Wrong" -} nBan :: [a] -> Int -> [a] nBan list number = case (list) of [] -> case (number) of number < 0 -> error"dame" [] -> case (number) of number == 0 -> error"dame" (x:xs) -> case (number) of number > 0 -> [x] ++ nBan xs (number - 1) _ -> error"Hen" どっちもなぜか違う。
MaybeってC#で言うところのint??
>>880 似たようなものだと考えていいけど、値を使おうとしたときに
中身がnullだった場合の処理を書くことを強制させられるという点が違う。
でもfromJustというチート関数があるので完全じゃない。
検索するとわかるから多少ましかも。
882 :
デフォルトの名無しさん :2013/03/16(土) 23:18:18.70
>>881 別に強制されないと思う
f x = let (Just y) = x in y
とか書けるし
>>883 それもそうですね
これ警告出せなかったっけ?
>>882 終わってもいいけど次の言語も半分は今までと同じになるよ
どの辺が同じになるのかも見当がつくから完全に白紙に戻ることはない
886 :
デフォルトの名無しさん :2013/03/17(日) 09:16:17.29
>>885 次の言語、どの辺が同じになるか、
面白いね。もうちょっとしゃべってよ
Haskell 参照透明性 OOP メッセージパシング
参照透明性なんてMLやpure LISPの時代から言われていることで Haskell特有でもなんでもない。 メッセージパッシングはとっくにOOPから捨てられただろ。 今のメジャーなOOPLはみんなメソッドを叩くだけだ。
ふーんw
オブジェクト指向のこころもMeyerのオブジェクト指向入門も読まずにOOP語ってる恥ずかしいやつが多いね
891 :
デフォルトの名無しさん :2013/03/17(日) 10:01:57.35
>>890 いいねえ
次は、オブジェクト指向のこころとMeyerのオブジェクト指向入門の
限界についても意見を聴きたいね
>>889 wてなんだ?
何がしたい
いいねえw
何も理解してないやつの「俺は会話についていってますよ」アピール
OOPLはOOが育てた、Haskellは育ててないといって OOが言語を差別するから、次世代の言語を同じだと思えなくなる それならOOの本を読まずにOOPLを語る方が良い
>>896 >OOPLはOOが育てた、Haskellは育ててないといって
ソースplz
ソースを要求する以前に
>>896 の意味がわからない
このスレ情緒不安定しぐる
ちょっと前に暴れてたやつと同じ臭いを感じる と言うか同一人物かな
第三次エスパー大戦の始まりか……
ここはHaskellのスレなのに、Haskellの関係ないOOの話を延々続けてる奴は一体何なの?
>>901 等式推論とかやりたいなら
あまり関係ないものでも等価だと主張するぐらいが丁度いいんじゃないの
OOとHaskellは全く無関係かというとそれもまたアレだし微妙だねえ 型クラス継承はメッセージOOの継承とは別物だけど メイヤーの表明OOでのサブタイプ多相は成立してるよね
OOはコーディングする本人の主観的な主義にすぎないから、機械語もOO
>>905 どこのスレのOO厨にフルボッコされたんだ?
俺がかわりにやっつけてきてやるよ。
>>905 抽象度と客観度は比例すると思ってる奴がいるんだよ
そういう奴は、抽象的であるOOが主観的なわけがないと思い込む
>>901 「完全教祖マニュアル」に、トンデモ論を言い続けていれば理論づけてくれる人が現れる、ってのがあるな。
いいねえwww
サブルーチンのバグを逆手にとって関数化するとは具体的にどのような意味なのでしょうか
これは俺も気になった
日本語の意味がわからないのを逆手にとってソースコードの読みやすさに気づかせる
Haskellって実用アプリ作れるの?
>>919 何か作ることができない訳を思い付きますか?
チューリング完全がどうたら↓
先に言うなよ!↑
>>920 Haskell製の商用ゲームがないこと
924 :
デフォルトの名無しさん :2013/03/20(水) 17:28:45.26
だれかHaskellでどうぶつの森作ってくれ
>>923 Nikki and the robotsはポシャったけど商用レベルじゃないんですか(泣)
>>925 残念だけど商用レベルを名乗るならPS3で出せるくらいのクオリティじゃないと・・・
なんかあったじゃん、Haskellオンリーの結構いけてるゲーム
と思ったら
>>925 のだった
PS3みたいにSPUを利用する環境こそ HaskellってSPUを使いこなすには有利だと思うんだけどね 現場じゃSPUまともに使いきれてないところ多いし
PS3で出せるくらいのクオリティに到達していない感がするゲームも 普通にPS3で出てるがな・・・ それはそうと、Haskellでゲーム作るなら、 データ駆動型が相性良いような気がするのだがどうだろう?
せやかて工藤
作ってから言え
Monadius www.geocities.jp/takascience/haskell/monadius_ja.html Quake clone の Frag とか www.haskell.org/haskellwiki/Frag 商用のアプリって質の低い実装者とテスターを大量に投入して作り上げるものだから 出来上がった中身は大抵がそびえたつクソなんだよな
そのクソすらできないのがHaskellと言いたいの?
ゲーム会社が商用ゲームを作るのにメイン言語としてHaskellを選ばないのは、 プログラミング言語としてHaskellがクソだからという理由ではなくて、 単にC/C++で何も問題なく上手くいっているように感じているからだ。 そもそも現場でプログラミング言語を比較検討するという行為が行われていない。 だから、Haskellに限らずJavaやC#、ErlangやOCaml、LISPなども使わない。 スクリプト言語ならいくつかの候補から選ぶが、 それは一般にスクリプト言語と呼ばれているものだけを候補にするため、 やはりHaskell(やJavaなど)は初めから候補リストに入る余地がない。
その文脈でMonadiusを挙げるのは、皮肉で言ってるようにしか……
IOwwwwwwww dowwwwwww
商用のアプリじゃなくても、日常業務で使うスクリプトでもいいんだけどね schemeで作ったCUIの2chブラウザをhaskellに移植しようとしたら、文字化けがひどすぎて投げた AAの表示は無理だよ、これ
ブラウザをschemeでとかHaskellでとか適材適所過ぎるェ…
何にしても大きいシステムを作るには関数型は部品が細かくなりすぎて逆に読みにくくなるのは仕方ないものなのかね
部品が細かいなら大きいタプルに入れればいいだけ Lispのようなタプルが読みにくいのは仕方ない JSONのようにすればよかった
大規模アプリでコケるのは、単体テストじゃなくて結合テストなんだから、純粋関数並べられても訳に立たない
>>941 「純粋関数並べられても訳に立たない」の意味がわからない。
大きなタプルとかアホ? 単にちゃんとレイヤー設計しましょう、ってだけでそ?
お前らが話しているのは、きっと作りにくい、きっとコケるだろうという予測の話。 実際に作ってみたが、ここで問題が起きた、どうすれば良い? という話は出てこない。
>>944 つまり、
「お前達、結合テストが必要となるような大規模開発やったことないだろ?」
ということですか。
C++以降の言語はみんな、Cはきっとこけるだろうという予想で作った言語だ 実際にこけたという話は出てこない
実際に何か作るような人はこんなスレに居ないんで
>>946 なんだかんだいって、最終的にCで実装することになる
その次に実装につかわれる言語がVBというおかしな世界
いつの時代の人間だよ
インフラ系は40年前のソフトのメンテやバージョンアップが主業務なんてのはザラでして…
大勢が憧れている安定した大企業の勝ち組IT土方の実態というものか
大企業Disのブームはもう終わりましたよ
冷静に考えたら、製品の劣化なし完全コピーが可能なんだから、新言語が普及しないのは当然 開発用ツールのスクリプトがタケノコみたいにポコポコ出てくるのも当然
メンテ用ツールか、旧言語のコードの自動生成しか新言語の活躍の場はない
実行は速いがコンパイルは遅いという伝統を踏襲しなかったから、スクリプトは新しい 相変わらずコンパイルが遅い言語はどこが新しいのか分かりにくい
今更だけどここのスレタイってあんまりよくないよな 言語の名前は最後じゃなくて頭のほうに持ってきてほしい
Haskell part 21 : 歴史
いいねえ
>>584 に書いたパルズ解答ソフトについて。
以前にC++で作ったソフトをHaskellで作りなおしてみた。
なんとか完成させ、新しい機能もちょっと追加。
とりあえず作った…。これから修正していこうと思う。
ソースコードサイズ(両方ともに未参照コード含む)
C++版 167kB
Haskell版 54kB
計算時間
C++版 1.77秒
Haskell版 38.2秒
962 :
961 :2013/03/22(金) 21:48:55.34
感想。 コードは短くなったけれども、思ったより短くない。 C++版とHaskell版は、両方ともスパゲッティ状態。 Haskellのほうが短いとはいえ、スパゲッティ状態もまた 濃縮されているようなものだ。 Haskell版のほうが計算時間が長いのは仕方ない。 "はじめてのHaskell"ではね・・。 これから改善して2秒以内にするのを挑戦してみる。
パルズ!
964 :
961 :2013/03/22(金) 22:31:56.28
>>963 「パズル」の間違いです。
「プログラミングin Haskell」は最後まで読んだ。
「すごいHaskell楽しく学ぼう」は、今200ページ前後を読んでいる最中。あと半分・・。
バルス
前者を先に読むのってどうなんだ ++がくっ付いた記号とかλとか→とか⇒とか 記号がおかしくて初心者は実際に全角を入力するし頭おかしいよあの本 2冊目としては良書なんだけどなんで記号使ってんだボケって言いたい
>>966 Haskell系の論文だと、そういう記号わんさか出てくるな。
著者も研究者だし、この本もどちらか言うと
関数プログラミングを学問として学ぶ系だと思うよ。
実用書じゃないオナニー本ってこと。
すごいHaskell〜も分かった気になるだけの本だしなあ
嫌な言い方をする人はコードも嫌な感じ
>>970 すごい本のこと?
確かになんかネラー臭のする言葉がたまに出るけど…
>>966 日本語版は巻末に書中で使われている記号と実際の入力方法の対応表が巻末に付いてるし
そこまで怒るようなものでもないんじゃないか
プログラミングHaskellは単にIFPHに倣っただけだろ
>>973 いや、学問は知識欲を満たすためのオナニーだよ。
記号の凡例は前書きや巻末にひっそりと載ってるから物言いがつくんじゃね 本文第一章あたりで堂々と説明しとけば初学者でも迷わないと思う
誰かモナデウスのソースコード解説を
すごいHaskellは原文からしてあの口調だからな しかしそこがいい
つい最近立ったと思ってたのになんでもう埋まりそうなんだよ
980 :
デフォルトの名無しさん :2013/03/23(土) 07:29:02.39
getで出したリストの値をcouで使用。get [1,3,4,3,4,7,4]->[4,4,7,4] それでcouでそのリスト内の4の数を求めたい。しかし、返された値は0。なぜ? get :: [Int] -> [Int] get list = case (list) of [] -> [] (x:xs) -> [x | x <- xs, x > 3] cou :: [Int] -> Int cou (list) = case (get list) of [] -> 0 (x:xs) -> case (x > 3) of True -> 1 + cou xs _-> cou xs
ごめん日本語の部分がよく分からない ちゃんと順序立てて言葉足らずにならないように説明してよ
すごいH、完全にLand of Lispに食われたなw
983 :
デフォルトの名無しさん :2013/03/23(土) 09:14:01.92
>>981 getは数値が3以下の数全てを除いたリストを返したい。例えばget[1,4,6,2,4,1]のリストは[4,6,4].
そして、couの関数でgetの返されたリスト([4,6,4])の中に何個’4’の数があるか?を数えたい。この場合[4,6,4]には4が二つあるので2を返してほしい。
cou [2,5,4,3,4] >> 2
式が間違ってました。
get :: [Int] -> [Int]
get list = case (list) of
[] -> []
(x:xs) -> [x | x <- xs, x > 3]
cou :: [Int] -> Int
cou (list) = case (get list) of
[] -> 0
(x:xs) -> case (x ==4) of
True -> 1 + cou xs
_-> cou xs
これでいいの? *Main> get [4,4,5] [4,5] *Main> get [4,5,4] [5,4] *Main> get [1,4,6,4,2] [4,6,4] *Main> get [4,6,4,2] [6,4] *Main>
986 :
デフォルトの名無しさん :2013/03/23(土) 10:50:27.19
わざわざありがとうございます。 getが何か変だと思い始めてます。 Main> get [3,4,2,4,5,4] [4,4,5,4] Main> cou [4,4,5,4] 2 -- 3を返して欲しい所 こんな感じになってしまいます。 get [4,4,5]の戻りはなぜ[4,4,5]ではなくて[4,5]になるのでしょうか?またget[4,6,4,2]もしかり。
987 :
デフォルトの名無しさん :2013/03/23(土) 11:04:15.91
get :: [Int] -> [Int] get list = case (list) of [] -> [] (x:xs) -> if x > 3 then x : get xs else get xs ようやく直せました。x | x<- xsではxが判定に入っていなかったからでした。色々ありがとうございました。
[4, 4, 5]を(x: xs)でパターンマッチするとxに先頭要素4、xsに残りの要素[4, 5]が束縛される あとcase式は使わずにトップダウンで定義を書き下したほうがいいと思うよ
?トップダウン ○トップレベル
>>987 ( x : xs ) -> [x | x <- (x : xs), x > 3]
こう直すだけでいい筈です。
>>987 >>988 の言うように 983 にある get の最後の行
(x:xs) -> [x | x <- xs, x > 3]
がおかしかった。
この書き方したいなら、
(y:ys) -> [x | x <- (y:ys), x > 3]
とかとするか、
y@(x:xs) -> [x | x <- y, x > 3 ]
とかかな。
get xs=[x|x<-xs,x>3]
内包表記とcaseを同時に使う必要はないね 使わないと機会損失だから同時に使うみたいなパターンは危ない
なんでコンスにしてんの?
995 :
デフォルトの名無しさん :2013/03/23(土) 11:54:25.38
トップレベルを調べてみます。 内包=if elseのことでしょうか? (x:xs) -> | x > 3 = x : get xs | otherwise = get xs だとエラーが出てしまったのでif使ってしまいました。まだよく分かっていないのですが、caseならcase, | なら |で統一した方がいいのでしょうか?ま〜名前がcouなのは適当に打ったからです。
>>995 こういうプログラムを書きたかったんじゃないのかな。
get :: [Int] -> [Int]
get list = case (list) of
[] -> []
(1 : xs) -> [x | x <- xs,x > 1]
(2 : xs) -> [x | x <- xs,x > 2]
(x : xs) -> [x | x <- (x : xs), x > 3]
cou :: [Int] -> Int
cou (list) = case (get list) of
[] -> 0
(x:xs) -> case (x ==4) of
True -> 1 + cou xs
_-> cou xs
よし、埋めはまかせろ!
バリバリバリ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。