関数型プログラミング言語Haskell Part6
スレタイこっちのがよかったな
【あらいぐま】関数言語Haskell Part6【ハスケル】
∩___∩
| ノ ,,. ,,ヽ
/ ● ● | 前スレ>996-1000全部もらったクマー
| ( _●_) ミ
彡、 ,、、|∪| ,,,ノ
/ . ヽノ ヽ
| _r'゚lニニニl]_ ____/l
fニニニニllニニ| \[ l===ニニl]}||||||||ll]}コl|====iニコ
|l_,,=-'''~ | \... ヽ'''ニ「_,,,l⌒l。__。_]三i三三iF
| 〈,,/ヽ___)|ll [`ー'
ミンナデ ハースケルー♪
∧_∧ ∧_∧ ))
(゙゙ヽ ゚∀゚)') ('(゚∀゚ /゙゙)
(( \ / ヽ /
((⌒) ( ) (⌒))
``ヽ_,) (,__,ノ゙
いいか、みんな
(゚д゚ )
(| y |)
Haskellで勉強すればokと信じていたのに、
いつまでたっても頭がよくならない。
Haskell ( ゚д゚) ok
\/| y |\/
これらをくっつけて
( ゚д゚) haskellok
(\/\/
逆から読むとこれ臭ぁ、というわけだ
( ゚д゚) kolleksah
(\/\/
Haskellやってると、くさくなるということだな
(゚д゚ )
(| y |)
9 :
デフォルトの名無しさん:2006/11/07(火) 23:20:08
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
□□□■□□□□■□□□□□□□□□□□□□□□□□□□□□□□□□■□□■□□□
□□□■□□□□■□□□□□□□□□□□□□□□□□□□□□□□□□■□□■□□□
□□□■□□□□■□□□□□□□□□■■■□□■□□□□□□□□□□■□□■□□□
□□□■□□□□■□□□□□□□□■□□□■□■□□□□□■■■□□■□□■□□□
□□□■■■■■■□□■■■□□□■□□□□□■□□■□■□□□■□■□□■□□□
□□□■□□□□■□■□□□■□□□■■■□□■□■□□■■■■■□■□□■□□□
□□□■□□□□■□■□□□■□□□□□□■□■■■□□■□□□□□■□□■□□□
□□□■□□□□■□■□□□■■□■□□□■□■□■□□■□□□■□■□□■□□□
□□□■□□□□■□□■■■□■□□■■■□□■□□■□□■■■□□■□□■□□□
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
前スレの998は死ね
>>10 ○
ノ|)
_| ̄|○ 「L
○、
\、 ○
ヾ \)ヽ
_| ̄| <
Haskellはじめて挫折して
(( (`Д´) (`Д´)
(/ /) (/ /) ))
< ̄< < ̄<
帰ってこないやつがいる
(`Д´) (`Д´) ))
(( (\ \) (\ \)
> ̄> > ̄>
ハイ!! ハイ!! ハイ ハイ
. ( `Д)_(Д´ )
. ノ ノヽ | |>
/ > < ヽ
ハイッ!!
(`Д´)_(`Д´)ノ
ノ ノヽ | |
. ノ > < ヽ
ハイ!あるある探検隊!
(`Д´)ノ (`Д´)ノ
<| ヘ| <| ヘ|
< <
あるある探検隊!
ヽ(`Д´)ヽ(`Д´)
. |,、 |>. |,、 |>
> . >
∧__∧
(`・ω・´) Haskellについて語るスレではござるのか?
.ノ^ yヽ、
ヽ,,ノ==l ノ
/ l |
"""~""""""~"""~""
、ミ川川川川川彡,,
え!? ミ 彡
l⌒l____l⌒三 ク .ハ こ 三
∩___∩ / 三 マ ス こ 三
/ノ ヽ/ ● ● 三 l ケ は 三
| ● ● i' (_●_,,) U .三 ? ル .ひ 三
| (_●_) 彡 l U | 三 の ょ 三
ミ l U l u l ヽ,_,,ノ 三 ス っ 三
>ヽ,,ノ ゝ ,,,;:三 レ と 三
/ /'' c-、 ,,,;;::::三 し .三
(二つ / (  ̄ ̄彡 て 三
〉 ( ̄ ̄'') `--──彡 .ミ
/ 、 >-─'' '川川|l|l |l|川川ミ
____)__
,. ´ ` ` 、
./ _ _ \
/ _  ̄ _ ヽ
/イィィ,,.,.,.,.,.,  ̄ ̄ !
f/ノノノノノノノ ヘ.__ j jノ__ノ
|/////// _ (__ ゚_>` __( ゚_イ
.!|.|i/_^ヽ|_'___r⌒ y' ヽ^)|
!|| fニ> :::::: `ー'゙ (_`___)ノ
ヽ.ニ` : /_ノ/川! / よし・・・・・
__ノ 、 / ヾ---'´ ノ
__ノ \l ` ____,/
\ ノ リ.|`ー--
\ .//
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/ , , , , , , __ ___` 、
,//////ィ ヽ.
ノノノノノノノl /\ , -、 !
///////l ",二ヽ.二_ヽ. l lノ_へノ!
//////ノ (_jリ ゙T`’ノ / (rリ`y゙
ソ´,-、\| -` ー--‐ " __{ ー-'{
| ,f^ソ |____/ ゙̄ヾ"´ \^ヽ. |
| に( l j ,.. ヽ |.| 俺もハスケる!!
\` ' j `ー-‐' イ_ ` ノ'" i
゙‐-' /,. ‐-、/TTT|| ノ
_} / |----二ニフ ノ
人\ ヽ. ! r'二ヽ / /
_「 \\ ` 、 ` ̄ ̄/
\\ Ti"
\\ ノ | |\
\ ∩─ー、 ====
\/ ● 、_ `ヽ ======
/ \( ● ● |つ
| X_入__ノ ミ 関数言語なんかに釣られ、ク、クマ―――――!!
、 (_/ ノ /⌒l
/\___ノ゙_/ / =====
〈 __ノ ====
\ \_ \
\___) \ ====== (´⌒
\ ___ \__ (´⌒;;(´⌒;;
\___)___)(´;;⌒ (´⌒;; ズザザザ
(´⌒; (´⌒;;;
------ 以上テンプレ -----
あらいぐまはPascalにくれてやれ也
19 :
デフォルトの名無しさん:2006/11/08(水) 12:10:07
Aranskが復活したの?
Aranskだけが馬鹿なわけじゃないと思うよ
やっぱりweb上に日本語で読める入門文書の一つくらい
あった方がいいんだろうか。
22 :
21:2006/11/11(土) 19:22:16
これだけじゃ意味不明だな。
「いっこうにHaskellがはやらないのを鑑みるに」を頭に付け加えてくれ。
formal semanticsが整備されれば利用者も100万人くらい増えるはず。
formal semanticsがあると何が嬉しいの?
バグに遭遇したとき、プログラムのバグなのか処理系のバグなのかが明確になる
>>25 自然言語で与えられるsemanticsではだめなのか?
それに、その用途に使うならHaskellで定義できないあらゆる関数(foreign importされたものとか)の
semanticsが必要になると思うんだが、それも要求しているの?
Rubyやperlだって言語仕様 = 実装だしな。
実用的なスクリプト言語にsemanticsなど不要。
形式的意味論なんて絵に描いた餅ですよ
Haskellは絵に描いた理想を追う言語ではなかったのか
>>28 形式的意味論もなにも、コンパイラとランタイムの
キャスト可否の判定が食い違ってるだけじゃん。
コンパイラ作成者がランタイムと違う実装してポカやっただけ。
本来なら A::compareTo(Object o) が呼ばれる。
ちょっとスレ違いですまん。
32 :
デフォルトの名無しさん:2006/11/12(日) 11:29:20
JAVA言語は危険だというkとが証明されたんだな
だな。c++のテンプレートよりかなりシンプルなのにこれだからな。
34 :
デフォルトの名無しさん:2006/11/12(日) 12:00:42
数学者の理想じゃね?
36 :
デフォルトの名無しさん:2006/11/12(日) 12:20:50
>>35 だからどんなのが理想なんだよ。
何か目的があってこそ理想があるんだろ?
いや俺
>>30じゃないからよく分からんし。
手続き型言語と比べて数式(数学者の脳内)に近いだろ?
だから数学者にとって理想的な言語。俺はそれくらいの意味で書いた。
Haskellはもう理想を失った・・・
実行時効率を犠牲にして言語を単純化しようとしているという点では
十分に理想主義的だと思うが。
文字列がコードポイントの遅延リストであるのがその一例。
ただのバイトのリストじゃない?
マルチバイト文字をリストの1要素として扱えてる?
>>40 Prelude> Char.ord maxBound
1114111
GHC6.6で、
main = print $ "テスト" !! 1
でもいいか。ソースはUTF-8で。
>>41 d。内部はUTF-16(的)なのね。
しかし、どうせならUCS4まで扱ってくれれば良いのに。
あんな「思ってたより多かったのでサロゲート作っちゃいました」
とかほざく連中に合わせる必要ないのに・・・。
>>43 いや、1114111は0x10ffffで、16ビットの範囲を超えていて、
Unicodeの17面を全部表現できる。
UTF-16よりUTF-32に近いはず。
Unicodeコンソ 2byte固定で全ての文字扱えるようにする。
ISO(10646) すげーな、頑張れ。でも2byteで大丈夫か?
Unicodeコンソ 大丈夫大丈夫
それぞれ仕様を策定することになる。(コードポイントはお互い合わせてる)
Unicodeコンソ Unicode(未定義含めて全領域は0..0xFFFF)定義しますた。
Unicodeコンソ 実装は固定長2byte(Unicode,のちのUTF-16である)です。
ISO(10646) UCS定義(未定義含めて全領域は0..0x7FFFFFFF)しますた。
ISO(10646) 実装は可変長(UTF-8)と固定長4byte(UCS-4)です。
少しして
Unicodeコンソ (やっべ)
Unicodeコンソ 0xFFFFで足りませんですた。サロゲートペアで拡張しますね。
Unicodeコンソ UTF-16にサロゲートの仕様を追加しますた。
Unicodeコンソ それと固定長(4byte)のUTF-32用意しますた。4byteだけど0x10FFFF以上は使うなよ。
Unicodeコンソ おまけ つ[0x10FFFFまでのUTF-8]
Unicodeコンソ というわけでよろしく。
ISO(10646) 0x10FFFFまでコードポイントを追加しますた。実装は変わりません。
Unicode対応と言いつつ0xFFFFまでしか扱えないソフトが出てくる ← 今ここ
追記:今のUTF-16は可変長な。UTF-32と同じく0x10FFFFまで扱える。
> UTF-16よりUTF-32に近いはず。
確かにイメージ的には32の方が近いね。実際どういう実装なのかは知らないけど。
内部表現は100進数だったりして・・・。
種は「根源的には同じもの」(亜種,など)で
類は「似た性質/特徴を持つもの」(哺乳類,など)と個人的に思っている。
で、kindの "* -> *" と "*" の区別とかは
「似た特徴」とも言えるが、それ以上に「根源的な部分」を
表しているような気がするので「種」に1票。
属とか科とか似たのもあるけど気にしない。
訳を当てずにkindって言うようにしてる
51 :
デフォルトの名無しさん:2006/11/16(木) 20:28:17
Haskellでオセロゲーム講座まだー?
52 :
デフォルトの名無しさん:2006/11/16(木) 21:02:53
>>48 ふだんごついのに
数学者のかわいい一面ですね。
厳密さが快感だから悩むのでしょうか?
でも、悩むの楽しいのでしょうね^^
頭わるすぎてワラタ
haskell全然わかんねー
i = 1
main = print $ myPlus i
myPlus :: a -> a
myplus j = j + j
これが動かないのはなんで?
エラーメッセージは?
- myplus
+ myPlus
- myPlus :: a -> a
+ myPlus :: Num a => a -> a
58 :
54:2006/11/19(日) 00:24:59
>>55-57 レスサンクス。コンパイル通ったよ。
でもなにこの「Num a => 」って奴は。haskellは簡単なことが難しいって本当だな。
とりあえず調べてみる。ありがと。
エラーメッセージを書こうね
60 :
デフォルトの名無しさん:2006/11/20(月) 07:04:54
諸君、議論したまえ
型システムについての解説ありますか?
モナドはたくさんあるけど
諸君、議論したまえ
お題: 巨大になりすぎたghcのスリム化について
66 :
デフォルトの名無しさん:2006/11/20(月) 21:55:44
GHCいれることにしたからWinHugsをアンインスコしようとした
そしたらダイアログでて以下のようなメッセージ
↓↓↓
=============================================================================================
C:\PROGRA~1\WinHugs\UNINST~1.EXE
C:\PROGRA~1\Symantec\S32EVNT1.DLL インストール可能なデバイスドライバはDLL初期化に失敗しました。
アプリケーションを終了するには[閉じる]を選んでください。
=============================================================================================
アンインスコ不可能になた
この前NIS2006を根こそぎ削除したのが原因のようなんだけど
こういう場合どうやったら引き続きアンインスコできんの?
67 :
デフォルトの名無しさん:2006/11/21(火) 00:20:35
ところで文字列"-123.456"を数値-123.456に変換する関数ってあったっけ?
これ?
read "-123.456" :: Double
69 :
66:2006/11/21(火) 01:19:16
ヘルプ!
>>606 Symantecとか関係なくWinHugsはなぜかアンインストールできない。
なのでさくっとスクリプトを書いてみようと思ったらひどい目にあった。
なんでマルチバイト文字とCharの相互変換もできないんだよ…
ttp://up.uppple.com/src/up0496.txt FFIを使う羽目になったので、GHCでコンパイルする必要がある。
あと無保証。BIOSが消し飛んでも関知しないから念のため。
72 :
66:2006/11/21(火) 21:39:06
>>77 うそーん
そんな不具合あんのかよw
公式ではまだその対策でてないの?
□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□□□□■□□■□□
□□■□□□□□■□□□□□□□□□□□□□□■□□□□□□□□□■□□■□□
□□■□□□□□■□□□□□□□□□□□□□□■□□□□□□□□□■□□■□□
□□■□□□□□■□□□□□□□□□■■□□□■□□□□□□□□□■□□■□□
□□■□□□□□■□□□□□□□□■□□■□□■□□■□□■■□□■□□■□□
□□■■■■■■■□□■■■■□□■□□□□□■□■□□■□□■□■□□■□□
□□■□□□□□■□■□□□■□□□■■□□□■■□□□■■■■□■□□■□□
□□■□□□□□■□■□□□■□□□□□■□□■□■□□■□□□□■□□■□□
□□■□□□□□■□■□□□■■□■□□■□□■□□■□■□□■□■□□■□□
□□■□□□□□■□□■■■□■□□■■□□□■□□■□□■■□□■□□■□□
ふつうのHaskellプログラミング買って勉強しはじめた
もう一冊のほうは知らんけど、これわかりやすくていいね
76 :
75:2006/11/23(木) 00:35:50
何がしたいねん
ひまやねん
スレがのびへんねん
諸君、議論したまえ
80 :
デフォルトの名無しさん:2006/11/25(土) 02:20:39
質問です。
HaskellにDoxygenのようなドキュメント生成のためのツールなどはありますか?
質問です
GHCとHugsという存在がよくわかりません
Haskellが仕様で、GHCとかHugsが実装環境ってこと?
もしそうなら、仕様ってなに?
どっかにそれをタンマリ書いたPDFとか置いてるの?
『Haskell』ってのはただの説明書?
それともLinuxに例えるならHaskellがカーネルで
GHCやHugsがディストリビューション?
やべぇ、余計わかんなくなってきた
>>82 覗いてみたけど眩暈した
>>81のLinuxの例えはあってるかな?
あってるなら納得する
Haskellは言語で、Haskell Reportはその定義。
GHCのような各処理系は、この定義に沿ってプログラムを解釈するように作られる。
言い替えると、Haskell ReportはHaskell処理系が満たすべき要件を定めている。
Linuxカーネルはディストリビューションが満たすべき要件を定めたりしないし、
カーネル自身がディストリビューションの一部なので、構造がだいぶ違う。
むしろ、POSIXとLinuxシステムの関係に近い。
いみわかんねーーー
どうも
>>83自身Linuxカーネルとディストロの区別がしっかりついてないんでは
つーかC++言語だってgccだのMS VC++だのBCCだのいっぱいあって,それで普通じゃん...
HaskellもHugsだのGHCだのいっぱいあるのですぉ
>>86 一般的なプログラマーならそれで理解できるだろうけど
Javaしか知らんのだよJavaしか!!1
Javaだってgcjだのjavacだのいっぱいあって…と言いたい所だが、gcjの知名度は低そう…
うん知らない
HTMLと各種ブラウザの関係と言った方がわかりやすいんじゃね?
HTML <-> Haskell98
IE,FF,Opera,etc... <-> GHC, Hugs, etc...
FFッテナニカトオモタ
え、そんな単純なことなのか
ibmのjavaがあるじゃない
コマンドライン引数を扱うプログラムってどう書くのでしょうか?
たとえば ghc でコンパイルして
C:\> .\fibonacci.exe 10
55
C:\> .\fibonacci.exe 20
6765
と動作するようなものを書く場合です。
またそれはどのあたりのマニュアルを参照すれば良いでしょうか。
>>93 hoogleでarg辺りで検索すればgetArgsが出てくる。
Stringってchar型の配列って書いてたけど、これってJavaでもいっしょ?
Javaの本ではそんなの読んだことない
>>96 そんな大嘘が書いているのはどこですか?
Haskellではcharの配列とStringはまったく違います。
また、Javaではchar[] != Stringです。
>>97 配列ではなくリスト、と言いたいんだよね?
Haskell の Array i Char と [Char] はぜんぜん違うデータだし。
実は、Haskellでは文字列もリストなのです。文字列は文字のリストとして
表現されていて、特別な「文字列」は存在しません。
ですから、リストの処理を覚えれば文字列処理も身につけたことになります。
-----ふつうのHaskellプログラミング
JavaのStringクラスはchar配列をラップしたものだね(ライブラリのソースを見れば分かる)
Haskellの文字列はCharのリスト(これを [Char] と書き表す)
Haskellでは配列とリストは別のデータ型.
関数型言語では大抵は配列よりリストのほうが頻繁に使われる.
うお、何かデジャブった
haskell初心者です。
次のコードは間違っていますか?それとも別の問題でしょうか?
import System.Posix.Files
main = getFileStatus "hoge" >>= (print . isDirectory)
ghciでは、ちゃんと動きました。
hugsで実行しようとすると、次のエラーが出ます。
*** glibc detected *** /usr/bin/hugs: free(): invalid pointer: 0x08f0d120 ***
======= Backtrace: =========
/lib/libc.so.6[0x4a74aefd]
/lib/libc.so.6(cfree+0x90)[0x4a74e550]
/usr/lib/hugs/packages/base/Foreign/Marshal/Alloc.so[0x4ed616]
/usr/bin/hugs[0x80771c6]
/usr/bin/hugs[0x8077bc0]
...
2chでは、知名度が低い分野のスレほどレベルが高い、という傾向がある。
つまりHaskellはもはやマイナーな分野ではない。
107 :
105:2006/11/26(日) 07:11:44
続き
ghcでコンパイルしようとすると、次のエラーが出ます。
t.o: In function `sHY_info':
(.text+0x8a): undefined reference to `unixzm1zi0_SystemziPosixziFiles_isDirectory_closure'
t.o: In function `sHW_info':
(.text+0x106): undefined reference to `unixzm1zi0_SystemziPosixziFiles_getFileStatus_closure'
t.o: In function `Main_main_srt':
(.rodata+0xc): undefined reference to `unixzm1zi0_SystemziPosixziFiles_isDirectory_closure'
t.o: In function `Main_main_srt':
(.rodata+0x10): undefined reference to `unixzm1zi0_SystemziPosixziFiles_getFileStatus_closure'
collect2: ld はステータス 1 で終了しました
OSはFedora Core 6
インストールしているパッケージは、
hugs98-2006.09-1.fc6
ghc66-6.6-1.fc6
ghc-6.6-1.fc6
です。
108 :
105:2006/11/26(日) 07:23:22
もうひとつ疑問があります。
次のコードが、hugsでは受け付けられるのに、ghci・ghcでは、
hoge.hs:3:10: parse error (possibly incorrect indentation)
などと、エラーになります。
haskellの言語仕様上、下記の記述は許されないということでしょうか?
main = do if True then putStrLn "t"
**********else putStrLn "f"
但し、半角スペースを記号"*"で置き換えています。
>>108 仕様上正しいかどうかは知らんけど、もう一個スペース入れればghcで受け付けるようになる。
もしくは、この例ではdoは必要ないから外してしまうとghcでもOK。
ghcではdo構文の中ではthenとかelseはifの開始位置よりも右から始めないとダメって事になってるのかも。
>>107 必要なライブラリをリンクさせてないってことでしょ。
単に ghc hoge.hs としたらhoge.hsだけをコンパイルして標準のライブラリとリンクさせて実行ファイル作るけど、
import System.Posix.Filesをしてるから標準のライブラリには含まれてないものを必要としてて、
それが足りないというエラーが起きてる。
-packge 〜 というオプションをつけて手動で必要なものを指示する方法もあるけど、
--makeオプションを使った方が必要なものを全部自動的に処理してくれるから楽。
ghc --make hoge.hs
111 :
105:2006/11/26(日) 11:37:13
>>109 書き換えれば動くのは確かめたのですが、
処理系によって挙動が異なるので、仕様ではどうなっているのか気になっています。
>>110 ありがとうございます。
たしかに、ghcに--makeオプションを指定すると、うまくコンパイルできました。
hugsでは、このライブラリは利用できないのでしょうか?
hugsの実行時に+wオプションを使い、読み込まれるファイルを確認しました。
結果、メッセージは
...
Hugs session for:
...
/usr/lib/hugs/packages/base/System/Posix/Types.hs
/usr/lib/hugs/packages/base/System/Posix/Internals.hs
/usr/lib/hugs/packages/unix/System/Posix/Files.hs
hoge.hs
Type :? for help
Main> main
*** glibc detected *** hugs: free(): invalid pointer: 0x0965eb60 ***
======= Backtrace: =========
/lib/libc.so.6[0x4a74aefd]
/lib/libc.so.6(cfree+0x90)[0x4a74e550]
/usr/lib/hugs/packages/base/Foreign/Marshal/Alloc.so[0xd67616]
hugs[0x80771c6]
...
/lib/libc.so.6(__libc_start_main+0xdc)[0x4a6faf2c]
hugs[0x8049c51]
======= Memory map: ========
...4a8アボートしました
となり、異常終了してしまいます。
>>108 if..then..elseは単なる式であって、doの文にするなら一文に収めないといけない。
そのコードだとif...then...とelse...で二文に分かれているので、エラーになるのが正しいはず。
手元のHugs May 2006では
ERROR "test.hs":2 - Syntax error in expression (unexpected `;', possibly due to bad layout)
というエラーになった。
115 :
114:2006/11/26(日) 13:30:35
なぜかWindows版だと通るな。
Hugsのバグかも。
>>105 明らかにライブラリまたはHugsの問題。コードは悪くない。
117 :
93:2006/11/26(日) 17:50:31
ttp://oss.timedia.co.jp/show/Haskell/Emacs に書かれている設定で Emacs の haskell-mode を入れてみたんですが、
インデントが正しくなりません。たとえば Yet Another Haskell Tutorial
の p.32 の例を入力すると、
module Main
where
import IO
main = do
hSetBuffering stdin LineBuffering
putStrLn "Please enter your name: "
name <- getLine
putStrLn ("Hello, " ++ name ++ ", how are you?")
となってしまいます。(半角スペース 2 つを全角空白文字に変換しています。)
何か設定がおかしいんでしょうか? それともこういうもの?
tabを何回か叩くとインデント位置の候補をローテートしない?
120 :
105:2006/11/26(日) 19:14:27
圏論やりながらHaskellやっているのって主にどこの大学でやっているんですか?
それともみんな個人レベルで圏論とHaskellをやっているんですかね・・・
122 :
118:2006/11/26(日) 23:59:42
>>119 おおー、なるほど。ありがとうございました。
>>121 いろんなところでやってるでしょ。代表的なのはオックスフォードだけど。
うぉ。
ていうかこれ去年か。
京都産業大学か
本物のプログラマをHaskellを使う
本物のプログラマでHaskellを扱き使う。
あなたをHaskellです
目的語指向言語のスレはここですか?
131 :
デフォルトの名無しさん:2006/11/28(火) 23:56:32
>>131 HelloWorldしか書けない初心者の俺がみても
10個中10個が失敗した理由になってねーよw
人気でない10の理由ってんなら少しはわかるが
>>134 ごめん全部読んだけど、面白くなかった。
何かお笑い芸人のネタみたい。
ギター侍を知っていることが前提のネタだから仕方がない
>3. 型推論も遅延評価も飛躍的な進歩というわけじゃない。
遅延評価はパラダイム的にはものすごい進歩だとおもうけど。プログラム言語内に無限概念を取り込むことに成功している。
数学チックにいうと
遅延評価のない言語=代数的
遅延評価のある言語=超越的
とでもいうか・・・。
遅延評価は何気にHaskellの一番の利点だと思う。(パラダイム的に)
型推論なんて比べ物にならね。(比べるものではないが、ていうか比べられないけど)
あんまりよく読んでなかったorz
遅延評価はHaskellの一番の欠点だと思う。
言語に組込みで持つには(計算機アーキテクチャから見て)複雑過ぎるし、
オーバーヘッドが大きすぎるし、空間効率の予測が難しすぎる。
たしかに遅延リストや遅延木は便利だけど、
それは言語に遅延評価を組み込む理由にはならない。
例えば遅延リストはOCamlやSchemeでも扱えるはず(違ってたらごめん)。
型推論とどっちを取るかといわれたら、俺なら間違いなく型推論をとる。
おめーら
専門用語きんし
↓以後ひらがな+説明文添付必須
結局は好みだよな。
だけど、言語機能として一貫して遅延させるのと単に遅延評価を扱えるってのとでは話が違ってくる事柄なので、
そういった形での比較はナンセンスだと思う。
遅延評価は遅延評価なりのメリットがあるので別に要らない場面ではOCamlでもSchemeでも使ってりゃいいんでね?
常に!つかえば
>そういった形での比較はナンセンスだと思う。
あー確かに議論が混乱してたかも。すまん。
>別に要らない場面ではOCamlでもSchemeでも使ってりゃいいんでね?
**が欲しいなら**言語を使え、というのは余計なお世話だ。
Haskellにあってその二言語にない特徴なんて遅延評価以外にもいくらでもあるわけで。
遅延評価=>ε-δ論法
すなわちHaskellは無限概念を内包しているのだ!
といってみる。
てめー記号まで使うな
よめないぞ
つーかIOモナドも遅延評価なかったら使えないだろ。
>>146 なんで?
確かに
main = putStrLn "foo" >> main
みたいなのは書けなくなるけど、
main = putStrLn "foo" >>= (\_ -> main)
と書けばいいので問題ないと思うんだが。
C++で書いてると、たまにHaskellが恋しくなります。
Haskellで書いてると、たまにC++を頼もしく感じます。
修行が足りない?
遅延評価無いとモナド使うのマンドクサ。
例外モナドがMaybe aではなく() -> Maybe aだったとすると
do
foo
bar
を
do
(\_ -> foo)
(\_ -> bar)
って書かないといけなくなる。
>>147 実装上の問題。正格では実装できない。おそらくね。
全然違うかもしれんが。
>>149 それは気づかなかった。
その例だとdoを展開するときに>>でなく>>=を使うようにするだけで十分だけど、
類似の例がもっとあるといやだな。
>>150 newtype IO a = IO (() -> a)
で十分なはず。
C++でIOモナドを書いてみたら一応動いたのでたぶん問題ない。
>>143 Haskellにとって遅延評価は基盤であり、その他の便利な特徴もそれを前提としているものが少なくない。
>>139の「それは言語に遅延評価を組み込む理由にはならない。」
というのがあるから嫌なら特に必要ない限り他の選択肢を選べばいいんでね?
という程度の考えだった。
逆に言えばHaskellの特徴の便利な部分をOCamlやSchemeでは実現しえないものか?
できないならやっぱHaskellの遅延評価とそのほかの特徴は切り離せないものと割り切るしかなかろう。
>>153 遅延評価がないと難しそうなもの(where節とか)もあるけど
そうでもなさそうなもの(型クラスとか純粋さとかインデントによる構文とか)も結構あると思う。
スーパーモ゛ナ゛ードッ!!
ヽ/\ , ,
| \ヾ // |, ,
ヾ //,,
\ ∧/|,//_ /"
ヾ ヾ,ヘヘ / ,/ /,
\ ヾ|/|/ヽノ/,/ /"
丶 (`∀´ ∨ /,
\ d つ /"
ヽ | | | /,,
\__,,,(_(__),,,_/"
遅延リストってジェネレータで代替えできるしなぁ
無限概念の話、無視しないで・・・。
>>156 遅延リスト(無限リスト)とジェネレータ(ストリーム)は
本質的に異なる構造を持っているので、理論上代替は不可能。
実用上はだいたい代替できるんだけどね。
理論屋としては別物として考えておきたい。
同じ終代数を持ちそうだがな
>>148 俺もだ。
だれかHaskellとC++とDとMerdとRubyとNemerleの良いとこ取りした言語
作ってくれないかな。
アセンブリを関数型で書いたりできないの?
Lambda, the Ultimate Label?
>>162 C++3xはそれらを全て取り込んだ究極言語になるらしいよ。
3xワラタ
言語仕様が10巻本で出そうだな。
>>139 >遅延評価はHaskellの一番の欠点だと思う。
遅延評価を実装することが、Haskellおよびその祖先のそもそもの目的だったのよ
遅延評価がHaskellの存在意義なの
最近Haskellの勉強始めたんだけど全然わかんね。
ラムダ計算や圏論とかモナドって考え方がさっぱりだ。
これって計算機科学や数学を勉強しなきゃならんね。
情報系の学部ってこんなんやってんの?
>>168 プログラミングは計算機科学じゃないから。
「情報工学」とかになるとプログラミングに関する事もやってたりするけど。
>>168 >ラムダ計算や圏論とか
haskell使うだけなら必要ない。
もしhaskellの入門本にラムダ計算や圏論が説明されていてもそこはすっとばしていい。
172 :
デフォルトの名無しさん:2006/12/01(金) 14:37:21
現時点で最強の関数型言語はエクセルです。
すべてにおいて
エクセル>>>>>ハスケル
ハスケル厨は勘違いしないように。
名前自体パクりっぽいよな。
だれか.NETに乗っけてくれ。
そうすれば必要なところではHaskell、あとはC#ですむ。
Haskell.netはあったはずだが…
>>171 そうなのか?俺も初心者だけど
そこを理解してこそ、Haskellを勉強する価値があるんじゃないのか?
>>175 それは何のためにHaskellを勉強しているかに依るだろ。
俺は数学的背景をほとんど知らないけど、Haskellで
快適にコーディングができる程度には「使え」るし、
Haskellを勉強して得たものは非常に大きいと思う。
もちろん、背景を理解すると見えるものが一変する、という可能性は
否定できないけど。
>>176 そのコードを自動でメモ化する処理系なんてあるのか?
さすがにそれを効率的だと言うのは誇張かと。
WinHugsどうやって削除すればいいですか?
直接レジストリ消そうと思うんだけど、どれ消せばいいのかわからない
Software以外に関係してるとこあるのかな
>>180 インストール時の選択によって違う。
詳しくは
>>70のgetRegsを読んでくれ。
HKEY_LOCAL_MACHINE hKEY_LOCAL_MACHINE SOFTWARE\\Haskell
HKEY_CURRENT_USER hKEY_CURRENT_USER Software\\Haskell
HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\WinHugs
hKEY_CLASSES_ROOT hugs_haskell
hKEY_CLASSES_ROOT hugs_haskell
この4つ消してあとはフォルダごとゴミ箱つっこめばOKかな?
>>182 >HKEY_LOCAL_MACHINE hKEY_LOCAL_MACHINE SOFTWARE\\Haskell
>HKEY_CURRENT_USER hKEY_CURRENT_USER Software\\Haskell
中身がhugsだけでないなら消すとまずい。
あ、そっか
GHCとかもその下に含まれてるね
その下のHugsってのだけ削除すればいいか
>>171 逆にその辺の知識を勉強したいと思った場合どこから手を付ければいいんだろう?
高校レベルまでしか数学知識ない状態で。
Jacobの黄色い本なんかがいいんじゃないか
>>185 現実的に言って働いている社会人だとほとんど不可能だと思う。
理由としては。
1.時間が馬鹿みたいに必要。(日常生活に確実に侵食してくる)
2.難しいのでモチベーションが続かない。(理系は視野が狭いというが狭い視野じゃなきゃやってられねぇ。)
3.自己流だと確実に変な方向に行ってしまう(数学基礎論にはまってしまってその考えから抜け出せなくなってしまうのがよくあるオチ。数学は記号論理学じゃない。)
まともにやろうと思えばだけれど。
>1.時間が馬鹿みたいに必要。(日常生活に確実に侵食してくる)
貯金が溜まりますねー
190 :
171:2006/12/03(日) 23:13:30
>>175 >>171は
>haskell使うだけなら
という限定つき。
たとえば、チューリングマシン知らなくてもC言語は使えるようになるし。
むしろ、基礎理論をうまく隠蔽できないなら、プログラミング言語の設計としては失敗といえるかも。
>>187 > 3.自己流だと確実に変な方向に行ってしまう(数学基礎論にはまってしまってその考えから抜け出せなくなってしまうのがよくあるオチ。数学は記号論理学じゃない。)
そんな奴みたことない。
それに、この分野、まだまだみんな自己流じゃないの。
数学や物理のように確立されたカリキュラムもないし。
>>191 そこからは自己流だがそこまで行くための基礎的な部分までの話。
基礎ができないと応用はできない。
GHCってhaskellで書いたソースをCに変換させてコンパイルさせているのでしょうか?
haskellソース→Cソース→アセンブラソース・・・
それとも直接アセンブラのソースに行くのでしょうか?
haskellソース→アセンブラソース・・・
上のほう
でも当然読めるようなCじゃない
場合によっては直接アセンブリを生成する。これは-fvia-Cと-fasmで制御できる。
>>191 1ヶ月でできるお勧めカリキュラム
1週目 λ計算。とりあえずD∞ modelあたりまでやる
2週目 型理論。ざざっとSystem Fまでやる
3週目 圏論。1,2週目の理解をもとにCCC modelまで。
4週目 記号論理学。LKLJNKNJの規則をながめる。
この後は興味に応じて論文を読み漁ればok
そのカリキュラム、相当ヒマで相当モチベーションの高い人間でも
こなすのが辛いような気がするんだが。
まあ進度は時間と能力に応じて変わるかも。
でも、この辺の分野は親切な入門書もたくさんあるし、自己流の罠? にはまることもないと思う。
社会人で独学で勉強していておかしな方向に行っている俺様が来ましたよ。
つーか。196は社会人なめとんのかい。
社会人の場合、一日にかけられる勉強時間でせいぜい30分とか
1時間だぞ。その時間をとれないことも多い。
しかも環境も劣悪で電車の中とか、仕事で疲れた状態だとか、あんまり
頭に入るような状況ではない。
こういう話を聞くとまた、過酷な勤務の底辺DQNプログラマか、と思う奴も
いるだろうけど(DQNなのはあっているが)、社会人で9時6時で帰れるような
職場はありません。9時ぐらいまでで帰れる職場でも同じで、それは一般的
には楽な職場と言われている。
しかもカリキュラムがいきなりλ計算。
高校卒業程度の数学力と言っているのにλ計算以前に勉強することが
あるだろうと小一時間...。つーか、記号論理学とかはλ計算以前に
やるべきだと思うがどうか。
むしろ独習の場合、自分のペースで学習が進んでかつ理解度を試される
ことがないので、解った気になって先に行ってしまうのがあらぬ
方向に進んでしまう気がするがどうか。早くカリキュラムを進める
理解力より、ゆっくり物になるまで粘る忍耐力の方が重要な気がするけど、どう。
200 :
デフォルトの名無しさん:2006/12/04(月) 20:47:03
>>196 やってみます。お薦めの本を教えてください。洋書でもいいです。
来週からλ計算開講だお
>>201 頼むぞホント
高卒でもわかるように説明できないようじゃ価値ねーからな
>>194,195
有り難う。
んじゃ、Cで関数書いて呼び出したり
アセンブラで書いた関数をCで呼び出して
その関数をさらにhaskellで呼び出すことも可能なのでしょうか?
ふーん、そこまで機能がそろっているのに
なぜ誰もOSを書こうとしないの?
アセンブラとCが使えるならOS作れそうな気が
するのだけれど。
そういう車輪の再発明っていうか、単に言語間の移植は、作ってるうちに空しくなるんだよ
ghcでアセンブラの勉強できないの?
210 :
187:2006/12/06(水) 11:24:57
>>199 >つーか、記号論理学とかはλ計算以前に
>やるべきだと思うがどうか。
やるとしてもかなり初歩の部分だけでいいと思う∀、∃、とかの意味をちゃんと「理解して使える」ようになればいいと思う。
あんまり込み入ったところは使わないしおそらく必要性もないと思う。
というかかなりごちゃごちゃしていてやる気がしないはず。(俺はしなかった)
>むしろ独習の場合、自分のペースで学習が進んでかつ理解度を試される
>ことがないので、解った気になって先に行ってしまうのがあらぬ
>方向に進んでしまう気がするがどうか。早くカリキュラムを進める
>理解力より、ゆっくり物になるまで粘る忍耐力の方が重要な気がするけど、どう。
理解度を試されるというところもそうなのだけれど、根本的に数学を理解するということを勘違いしていることが多い(勘違いしていました。)
数学は語学です。
おそらくもっともいい方法は圏論勉強会に一回だけでも出てしまうのがいいと思う。(ちなみに俺は行った事ない)
なんとなく方向性はつかめるんじゃないかと勝手に思う。
>>210 察するに、あなたは「自己流」でなんとかなったんじゃないの?
212 :
199:2006/12/06(水) 20:00:59
> あんまり込み入ったところは使わないしおそらく必要性もないと思う。
> というかかなりごちゃごちゃしていてやる気がしないはず。(俺はしなかった)
こういうところで手を抜くと、後々しょうもないところで限界がくる
というか、学習に広がりがなくなると思うのでやった方がいいと思うけど
どうなんでしょう。それこそ独学の罠なんじゃないんでしょうか。
計算機科学の勉強は何も関数型言語だけじゃなく、論理学がつかわれている
データベース、公理的意味論、モデル検査などなど色々面白そうな
トピックスがあるのでこれらを楽しめないのは損...だと思うんだけど。
当然、関数型言語の勉強をするにも論理学はあった方がいいと思うんだけど。
そういう意味では、記号論理学は語学、だな
もうちょっとわかりやすくて楽しそうなスレになりませんか?
論理学だの計算機科学だのそんなことはどうでもいい
ここはム板で、Haskellでプログラミングすることに関するスレだ。
関係ない話は情報学板・数学板でやれ
以後、ラムダ計算とか圏論とかの話題は禁止な
そんなことよりラムダ計算とか圏論とかの話しようぜ
そんなことより鮫の話しよーぜ
そんなことよりオセロやろーぜ
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │○│●│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │●│○│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │○│●│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │●│○│ λ│ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃
┗━━━━━━━━━━━━━━━━━┛
>>215 そんなに固いこといわなくても。
理論よりの話題が多いのは、そっちに興味のある住人が多いからだろう。
そもそも過疎スレで、Haskellでのプログラミングについてだって
盛り上がっているとはいえない(いったいHaskellでコード書いてる奴が
どれくらいいるのか)んだから、無理に話題をしぼってもいいことはないと思う。
もちろん、興味のない議論が長々と続くのは不愉快だと思うが、
その時は自分でネタを出すくらいの勢いで。
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │○│●│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │λ│λ│λ│λ│ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ &│ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │○│●│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │λ│λ│λ│λ│ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │&│ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │&│●│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │λ│&│λ│λ│ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │&│ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │&│ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │&│●│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │λ│●│λ│λ│ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │●│&│ │ │ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │&│ │ │ │ │┃ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │&│&│ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │λ│●│λ│&│ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │●│&│ │ │&│ │λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ │ │ │ │ │┃ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │●│ │ │ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │●│ │ │ │ │λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │●│&│ │ │ │┃ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │λ│●│λ│&│ │ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │●│&│ │ │&│λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │ │ │ │ │ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │ │ │ │ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃ λ...
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │ │ λ... λ... λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ λ... λ... λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ λ... λ... λ... λ... λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ λ... λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ λ... λ λ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─λ...
λ... λ...λ... λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │ λ... λ... λ...
┃├─┼─┼─┼─┼─┼─┼─┼λ... λ...
┃│ λ... λ... λ...
┃└─┴─┴─┴─┴─┴─┴─λ... λ...
┗━━━━━━━━━━━━━━━━━┛
鮫って魚が交尾するから鮫って書くんだぜ
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │∃│∃│ │ │ │ │┃ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │●│∃│ │ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│∀│ │ │●│ │∀│ │ │λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │∀│ │●│&│ │ │ │┃ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │∀│λ│●│λ│&│ │ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │●│&│ │ │&│λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ ∀ λ...
┃│∃│ │ │ │∀│ │ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │∃│ │∃│ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃ λ...
┗━━━━━━━━━━━━━━━━━┛
┏━━━━━━━━━━━━━━━━━┓
┃┌─┬─┬─┬─┬─┬─┬─┬─┐┃
┃│ │ │∃│∃│ │ │ │ │┃ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │ │ │∨│∃│ │ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│∀│ │ │⇒│ │∀│ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃
┃│ │∀│ │∨│&│ │ │ │┃ λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │∀│∧│∀│∧│&│ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │⇒│&│ │ │&│ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│∃│ │ │ │∀│ │ │ │┃λ...
┃├─┼─┼─┼─┼─┼─┼─┼─┤┃ λ...
┃│ │ │∃│ │∃│ │ │ │┃
┃└─┴─┴─┴─┴─┴─┴─┴─┘┃ λ...
┗━━━━━━━━━━━━━━━━━┛
λがいなくなってすっきりしたな
ParserCombinator とかだと簡単過ぎて、
文章書いてる、または、データ入力の仕事している気分で全く面白くない。
parsecに浮気したこともあったが、結局左再帰の処理が
鬱陶しくなってhappyに戻った。
>>211 ならなかった。それ気づいたときなんか毎日泣いた。
だからなんか粘着気味にレスしてる。
>>212 記号論理学は(偏見かもしれないが)直感が効かない。
数学でも直感てすごく大事。
あれはほぼ超絶テクニックのアルゴリズムの塊だから
やっても面白くないと思う。
最初から直感の聞かない数学の分野やっちゃうと
それが数学だと思っちゃう。まぁそれも確かに数学
なんだがあれは自分の人生をそれにすべて費や
しているような人がやるもんだ。
たとえば、基礎論とかゼータ関連ね。
煽りとかじゃなく
>>212はブルバキって知ってるか?
ん。なんかよく読むと趣旨がわからなくなっているな。
まぁ要するに
>>212が必要としている論理学のレベルは
ほかの分野の数学やっていれば自然に身につく。多分。
だったらほかの直感の効くわかりやすい分野から始めた
方がいいんじゃないかと。
あえて記号論理学みたいな諦める可能性90%なやつから
始める必要なんてなかろう。必要性が出てきたときに勉強
すればいいんじゃないかと。
すれ違い
いい加減ウザい
圏論理解するのにどんくらいかかる?
高卒で数IIもわからんし、基本情報処理もさっぱり
基礎も何も無いのに、かっこよさそうだからと飛びつくような人間は、
どんな分野も一生理解出来るようにはならんよ。
くっだらねーレスしてる暇あったら馬鹿にでもわかるような説明考えろよ
>>239 日本に圏論を理解してると自覚している人が誰もいないのに?
244 :
199:2006/12/08(金) 04:14:43
ブルバキの名前も知らないと思われているところをみると、
本当に何も知らない人なんじゃないかと思われているような。
たぶん、想像しているレベルの論理学のイメージはそんなに
変わらないはずだよ。
自分もそんなにディープな論理学の知識はいらんと思うが
(それはやぶ蛇)、自然に覚えるのでなく、それ用の入門書
ぐらい嫁というスタンスなんだが。俺もそれ以上はやってない。
> あえて記号論理学みたいな諦める可能性90%なやつから
どこまでやって諦める可能性90%というのか知らないけど。
言われてみればそんなに簡単ではないのは確かにそうだな。
まあHaskellスレに来るような人にとってはλ計算の方が
記号論理学より入りやすいんじゃないかな。
プログラム言語だし。
わかってみれば浅い話でも、
いきなりシーケント計算とかみると投げ出すでしょフツー
>ブルバキの名前も知らないと思われているところをみると、
>本当に何も知らない人なんじゃないかと思われているような。
名前だけじゃなくてその集団の目指したこととその失敗のことを
言っているんじゃないか。
ブルバキについて言及する奴の99%は、その著書を1ページも読んでない。
数学原論をまともに読む気するか?
conceptual mathematicsにはファンクタも出てこないじゃないですか。
ってamazon(us)で批評されてたけど、
実際、Haskellプログラミングや関連論文読む力付ける目的に合ってるの?
結構長いし、ちょっと不安す
!!ファンクタ出てこないの?
でも、いまつづいてる連載ってfmapを結構頻繁に使ってない?
>>250 俺も conceptual mathematics をざっと読んだけど出てくるのは product, sum, exponetial まで。
でも具体例でじっくり書いてあるので足元を固めて自力をつけるのにはよいかもしれない。
理解してたつもりでも実際練習問題解くとむずかしいものも多い。
取りあえず浅く知って(真に理解したという意味ではないよ)早く先に進みたいという人には向かない。
253 :
252:2006/12/09(土) 01:50:51
補足
equalizer も確かでてきてた。
「自力をつける」は「地力をつける」だった。
そういえば圏論勉強会の結果みたいなホワイトボードの写真あるけど
ほとんど説明無い。ほとんど有向グラフの図ばっかり。
あの図だけ見て何が何をやっているのか理解している人いるの?
255 :
252:2006/12/09(土) 03:37:30
>>254 同じテキスト読んでればボートの図だけで大筋何を言わんとしているかは想像できる。
素直に圏論の基礎読めば良いんじゃね。
なんでわざわざ洋書にこだわるんだ。
そんなもんオマエ…マクレーンが読めるようならこんなとこにおらんやろ
なんだか不穏な空気が流れてきたな・・・。
もうこの話し止めほうがいい気がしてきた。
さすがにもはや Haskell から遠ざかりすぎだしな
Haskellプログラミングでは圏論をあまり意識しなくても良くなっている。
これ以降圏論の話は数学板か情報学板でするように。
>>260 いや。ファンクタだけは理解しておいたほうが良いんだよ。
fmapがちゃんとつかえるのと使えないのとでは結構違いがある。
liftMも同じく。
使い方を間違える。
圏論を理解していないとfmapがちゃんと使えないって例えばどんな場合?
なんていうか読みづらくなる。
使い方を間違えるって言うのはおかしかったな、すまん。
ふと思ったんだが、fmapとliftMをHaskellで日常的に
使ってますって人ってどれくらいいるもんなんかな?
連載では多用しているけど。
つまり、理想的な書き方と比べて意味的には同等だけど
読みづらい書き方になる、ってことか。
どっちにしても例が欲しい。
>>268 fmapは使わないけどliftMは日常的に使う。
例・・・。そうだな。極端な例だと
`fmap`,`liftM`みたいに中間演算子的に使われると
どういう意図でそれをつかっているのか意味がとれない。
あとは、できるだけ
たとえば
calc :: a -> a
という関数があったらIOモナド用に
calcIO :: IO a -> IO a
calcIO = fmap calc
みたいに使ってもらったほうが構造だけは同一で元となっている
カテゴリーだけが違うということが明確になっていいんじゃないかと
思っている。
うーん。うまく伝わっただろうか・・・。
というかあまりいい方法じゃないのかなとか思ってきた・・・。
なるべく根本的な関数定義はラムダ計算のカテゴリー内で
やってしまって後はカテゴリーごとにfmapするなりliftさせるなり
したほうが再利用できるようになるし。
sample :: a -> IO a
なKleisli射はなるべく作らない方向性でいくべきなんじゃないかって。
モジュール化も損なわれるんじゃないかと。
でもそこまでいってしまうと作れなくなってしまうというジレンマに陥って
しまうから・・・。どうなんだろうねぇ。。
>>270 レスありがとう。
>`fmap`,`liftM`みたいに中間演算子的に使われると
>どういう意図でそれをつかっているのか意味がとれない。
これは俺も時々やるんだが、気持ち悪いと感じるのはたぶん分かった。
圏論の観点からはfmapは(射に作用する)単項演算であって
二引数関数のように使うのは不自然だ、ということか。(素人なので間違ってたら教えてくれ)
このスタイルを弁護しておくと、Haskellではあらゆる場合について
(g f) x
と
f `g` x
が等しいので、後者を見た読者は前者を見たのと同じように理解することが期待されている。
だから、両者を単純に字面上のおさまりに基づいて使い分けることができる、という考え方が
あり得ると思う。例えば f x の代わりに f `id` xと書くのがそんなに変だろうか。
加えて、それを言い出すと(>>=)だって圏論的には一引数の演算なんじゃないか、とか。
calcの例は理解できなかった。せっかく説明してもらったのにすまん。
>>271 それは例えば標準入力からCSV形式のデータを読みたいときに、
getCSV :: IO [String]
のようなものをgetChar/getLine/getContentsを使って書くよりも、
parseCSV :: String -> [String]
を用意してユーザ側でfmap parseCSV getContentsとさせた方が良い、
という理解でおk?
それなら多くのHaskellユーザが経験的にやってることだと思うんだが。
>272
>圏論の観点からはfmapは(射に作用する)単項演算であって
>二引数関数のように使うのは不自然だ、ということか。(素人なので間違ってたら教えてくれ)
その通り。というかそう自分としては解釈している、というほうが適切かな。
人によっては他の翻訳もありうると思う。
>このスタイルを弁護しておくと...
そういうスタイルがあることは最近知った。
前スレで出てきたLaw and Order in Algorithmicsってpdf内が
そういう流儀だったしおかしくはない。
でも、個人的に同一カテゴリー内の射(a -> a, IO a -> IO a)
なら「有り」だとは思うけど、fmapとliftMの場合そうやっちゃうと
ファンクタとかリフトって概念を持ち出す意味がなくなる。
>加えて、それを言い出すと(>>=)だって圏論的には一引数の演算なんじゃないか、とか。
圏論的には(>>=)は概念的にfmap,liftMの持つ概念と別種。
(といいつつそこらへんはよくわかっていないからどうともいえない
というのが本音。別種であるのは確か)
>calcの例は理解できなかった。せっかく説明してもらったのにすまん。
>圏論の観点からはfmapは(射に作用する)単項演算であって
ということなんだけどちょっと例が少なかったか。
(というか勝手な見解だからあんまり惑わされないでくれ)
というわけでもっと例をあげると
calcMaybe :: Maybe a -> Maybe a
calcMaybe = fmap calc
calcList :: [a] -> [a]
calcList = fmap calc
calcF :: F a -> F a
calcF = fmap calc Fは任意のFunctorクラス。
みたいなかんじに使えないかと。
・・・でも、やっぱり適用できる場面はそんなに無いか・・・な。
>>273 そういうこと。そしてそれがファンクタの概念。
経験的にわかっていることならこの際明確にしてしまおう。
なんかえらそうに書いてしまったが
これはすべて個人的な勝手な解釈だ。
なんかレスくれ。いろいろと穴はあると思うし。
>>275 >みたいなかんじに使えないかと。
つまり、IOならIOについて(fmap calc)をひとかたまりとみなすべきであり、
そういうスタイルを奨励するためにcalcIOという名前を付ける、ということか。逆に
do x <- a; b (calc x)
のようにcalcの適用をdo式中に散逸させたりすると、
この構造がわかりにくくなるので良くない、と。
ただ、相変わらずこのように書くことの現実的利益がわからない。
>構造だけは同一で元となっている
>カテゴリーだけが違うということが明確になっていいんじゃないかと
>思っている。
の部分。
>経験的にわかっていることならこの際明確にしてしまおう。
もちろん明確にするのは価値があると思うし、そういうのは
個人的に好きな方向性だけど、もともとの議論に関して
「圏論を知らないとHaskellを使うのにどれくらい支障があるか」という点については、
はっきりさせておきたかった。俺としてはHaskelll(のような言語)が
真に一般に普及してほしいと思っているので、経験だけではカバーできない
重大な困難があるかどうかが気になった。
>>278 >つまり、IOならIOについて(fmap calc)をひとかたまりとみなすべきであり、
>そういうスタイルを奨励するためにcalcIOという名前を付ける、ということか。
いや、そこまで強くは言っていない。名前付けたのはわかりやすくするためで
>>273みたいな名前付けない使い方が一般的だと思う。
というか経験的にすでにわかってることなんだと思う。
>ただ、相変わらずこのように書くことの現実的利益がわからない。
考えを整理できるとかそういう部類で現実的利益といわれると無いね・・・。
>「圏論を知らないとHaskellを使うのにどれくらい支障があるか」という点については、
>はっきりさせておきたかった。俺としてはHaskelll(のような言語)が
>真に一般に普及してほしいと思っているので、経験だけではカバーできない
>重大な困難があるかどうかが気になった。
Haskell使用するというレベルでは圏論の知識の有無による
困難は表面的には無い。が根源的には結構困難があると思う。
おそらく人のコードを読むという段階であらわに出てくるハズ。
fmapにしたってファンクタの概念をつかって圏論チックな考え方で
使おう思っている人と、そうじゃない人だと使い方が違う。
そういうのが積み重なって人によってはその書き方の意図が
読めないコードというのが出てくると思う。
そういう意味では結構困難がある。
まぁ要するにコーディングスタイルの問題。
圏論的なものを取り入れたHaskellコーディングスタイルを確立する
のかあくまで経験的なコーディングスタイルを確立するのか。
うーむ。なんだかグダグだになってしまった。
とりあえずfmap,liftMは便利じゃね?ということを
最初は説明したかったんだがものすごく言葉足らずでスマン。
>>279 「現実的利益」なんて嫌らしい言い方をしたが、ようするに
「それで何がうれしいのか」を聞きたかっただけだった。
「考えを整理できる」というので十分。
>考えを整理できるとかそういう部類で現実的利益といわれると無いね・・・。
圏論的な考え方を身につけた人にとって考えを整理しやすい書き方、ということでいいだろうか。
>Haskell使用するというレベルでは圏論の知識の有無による
>困難は表面的には無い。が根源的には結構困難があると思う。
>おそらく人のコードを読むという段階であらわに出てくるハズ。
いいたいことはたぶん分かった。もちろん実感として分かるわけじゃないので
自信を持って理解したとはいえないが。
俺としては、「表面上」支障がなければそれで十分だと思う。
例えばライブラリを提供する/使うだけならスタイルの不一致は問題にならないし。
しかし冷静に考えると、表面上支障がないというのは誰に聞くまでもなく俺が
身を持って知っていることだった。これじゃ何が聞きたかったのか分からん。
結局聞きたかったのは「圏論ってそんなにすごいの?」だったような。
ぐだぐだ
>とりあえずfmap,liftMは便利じゃね?ということを
>最初は説明したかったんだがものすごく言葉足らずでスマン。
とんでもない。言葉の通じない相手に長々付き合ってくれたことに感謝。
281 :
239:2006/12/10(日) 01:04:10
>>243 うん
それ読んでもつまらない
まだ早いようだ
f `fmap` a
は後置演算子と考えればOK。
つまり
(f `fmap`) a
。
>>280 >圏論的な考え方を身につけた人にとって考えを整理しやすい書き方、ということでいいだろうか。
まぁせっかく勉強したんだから使っていこうじゃんという気持ちも大きい。
>俺としては、「表面上」支障がなければそれで十分だと思う。
>例えばライブラリを提供する/使うだけならスタイルの不一致は問題にならないし。
その通りだと思う。ただ圏論の概念の名前を冠した射(ファンクタ、リフトetc..)は
(個人的に)理解して欲しい。
ちゃんとそういう名前がついているわけだし。
>結局聞きたかったのは「圏論ってそんなにすごいの?」だったような。
実際的な利益はほとんど無いんじゃないかと思う。
一般的抽象のナンセンスといわれるようにすごくないと感じる人も
いて全然おかしくない。個人的な価値観の問題なのかな。
ただ、モナドに関する情報の中でどれが有意義な議論なのか
見分けることができるようにはなった。
あと、うまくいえないがしっくりとする。
なんかしっくりとこないなぁというひとはちょっとやってみると
いいんじゃなかろうか。
>>282 スマン寝ぼけて無視してた。
Functorクラスでfmapの定義
fmap id = id
fmap (f . g) = fmap f . fmap g
とあるけどこれはまんま圏A、B間のファンクタFの定義
F( id_A ) = id_B
F( f_A ・ g_A ) = f_B・g_B
と同じ。
ただ、厄介なことにfmapがファンクタというわけではない
(ファンクタを構成するarrow functionというものにあたる)
arrow functionこと射関数っていうのは関数を圏の異なる関数に
移す関数。(関数というと語弊があるから「作用」というべきか)
うむ。そうだfmapは関数ではない。「関数」に作用する「作用素」と
見るべきだから中間演算子として使うのはダメ。
というのではどうですか。
なんか変なことかいてしまったかも。
まぁfunctionって意味が広いんだよ。
それを全部functionという単語の元
素朴な関数概念で置き換えちゃうから・・・。
うーん。自分でいっててよくわからん。
真偽は自分で考えてくれ。
圏論を知っても頭は整理されない、ということだけはわかった
287 :
デフォルトの名無しさん:2006/12/10(日) 17:02:27
確かにね、否定できんな。
まぁグダグダだしね
関数型超初心者なんですが、圏論を使うとプログラムとかでこんなにエレガントになるという例とかってありますか?
すみません、こちらはもっとベタな質問なのですが、
HaskellのFunctorと、C++のファンクタって、何か関係がありますか?
C++のファンクタは、単なる呼び出し可能のオブジェクトなのですが。
>>289 どちらも語源がfunctionである、という以上の繋がりはないと思う。
じゃあHaskellのファンクタとOCamlのファンクタは関係ある?
289じゃないけど便乗。
C++のファンクター、カンケネー♪
OCamlのファンクター、カンケネー♪
OCaml のファンクタも Haskell のファンクタも、圏論のファンクタ(関手)を
ベースにした概念という意味では関係がある。
C++のファンクタはまた違う語源のものなので関係ないという話をどこかで読んだことがある。
295 :
289:2006/12/11(月) 21:16:52
皆さん、ありがとうございます。
C++とは関係ないのですね。しきりに首をひねっておりました。
俺も質問させてください。
words関数やlines関数の実装で、リストのリストを返す方法がわかりません。
"hello world" を引数に取って["hello","world"]と返す関数はどのように実装したらいいでしょうか
f "hello world" = ["hello","world"]
f _ = []
>>290あの記事を理解できる時点で低レベルじゃない
>>290 互換性のために残ってるのだと思う。
単相性制限があるから、単純にmapをfmapに置き換えることは出来ない。
302 :
289:2006/12/12(火) 17:25:36
>>298 おお!向井さんの所でまとまっていたとは!
>>300 いや、私には難しいので、読むのにすごく時間がかかります。
だけど、入門Haskellのモナドまでを読めば、何とか理解できる範囲だと思います。
圏論の全く分からない私にはありがたい連載です。
何より、とても面白いと思います。
>>301 やはり過去互換性ですか。単相性制限?が分かりませんが、だからfmapという
新しい名前を作る必要があったのですね。
質問です
Visual Haskellをインストールしようとしたところ、
WindowsHostScriptで「Failed to setup vs_haskell.dll」というエラーが出たのですが、
これを解決する方法はありませんか?
よろしくお願いします。
使うな。
ありがとうございます。
解決しました。
map関数がわからん
使うだけなら簡単なんだけど、型の宣言がつじつま合わないというか
とにかく納得できない
ふつうのHaskellプログラミングみながら勉強してんだけど
ここで3〜4日停滞してる
square n = n * n
map :: (a -> b) -> [a] -> [b]
map square [1, 2, 3]
この場合の「map関数」の宣言、最初の「a」が「square関数」を指しているのか?
@(a -> b)の部分で「square 1」「square 2」「square 3」と計算して
A???
>>307 a->bはaを受け取ってbを返す関数の型。
mapは「aを受け取ってbを返す関数」とaのリストを受け取って、bのリストを返す関数。
a->bにあたるのはsquareだけだよ。
Haskel 全く知らんけど、それって
map :: (a -> b) -> ( [a] -> [b] )
(map square) [1, 2, 3]
ってこと(文法も知らんが)?
310 :
307:2006/12/15(金) 23:53:33
>a->bにあたるのはsquareだけだよ。
ソウイウコトカ!!!
スッキリー、スッキリ-
>>309 そうそう。haskellの多変数関数は関数を値とする一変数関数。
文法もそれでもあってるはず。
312 :
デフォルトの名無しさん:2006/12/16(土) 13:01:08
ところでkleisliの読み方がわからないんですがクライスリ?
Hugsのcompile.cなど一部のC source fileは
-O2無しでcompileされるようにMakefileinが書かれているけど
C compilerの最適化の副作用を避けるため等のなにか理由がある?
どうだろう。
変数がレジスタに乗ってしまってメモリ上から消えると、
GCを前提とした言語処理系では問題になることがあるみたいだが。
>>314 それはない。
しかし、レジスタ上だろうがメモリ上だろうが、変数が元の値ではなく
加工された値でしか存在しないという状況はあり得て問題になる。
>>313-315 ある特定の処理系の組み合わせで問題が起きることはあるかもしれないが、
常に問題が起きるってことはない。ソースコードが間違えていないなら、ね。
ソースコードは間違えているけど「ある処理系では問題が起きない」てのは
よくある話。
-O2の付け忘れでなければ、まずいコードになっているのかも?
volatile は役に立たんのけ?
>>317 役に立つ。というか必要なところにvolatileがないのはダメだろ。
スレ違いなんでこのへんで
だれかHaskellの再帰について教えて
くわしく、わかりやすく、ていねいに
aaa :: Int -> Int
aaa a = aaa (a+1)
let
空 = 色
色 = 空
in Data.Set.singleton 空
わからん
おまえの説明はまったくわからん大滝 秀治)
再帰という概念がわからないのか、それとも Haskell における再帰の取り扱いがわからないのか、どっち?
Javaの再帰はいちおう書ける
スマンがねる
良レスに期待
再帰を身体にしみこませるのにHaskellを使わない理由があるのか?
prolog
325を読んで疑問に思ったのだが、
hoge n 0 = n
hoge n c = hoge (n + 1) (c - 1)
hoge2 0 = 0
hoge2 c = 1 + hoge2 (c - 1)
hogeは末尾再帰だと思うのだが、hoge2も最後にhoge2があるから末尾再帰なのだろうか。
それとも、1 + hoge2が最後の処理だから末尾再帰じゃない、っていう解釈をするのかな?
331 :
329:2006/12/19(火) 19:13:04
>>330 ありがとう。
それにしてもレスが速いな(・∀・;)
ついでだから実行速度を測ってみた。
最適化しないとhogeの方が若干速いが、-Oをつけると同じ速さになる。
なんか切ないな
>>331 Haskell では末尾再帰について特に大きなメリットはない。
普通は末尾再帰は逐次計算していけるのから嬉しいのだが、
Haskell は最外簡約を取るので、逐次計算は行われない。
>>332 >Haskell では末尾再帰について特に大きなメリットはない。
そんなことはないと思うが。
Haskellは常に最外簡約というわけではないし
(GHCは正格性解析の結果に基づいて簡約順序を決める)、
最外簡約の場合でも、クロージャを作って別の関数に渡す代わりに
直接呼んでしまえるのでコストが小さい。
なぁなぁ、教養科目で記号論理学だけやったんだが。
推論規則の演習とかやった記憶もかすかにあるんだが。
圏論とかサパーリ。
もとが哲学寄りの文学屋なので、そっち方面の記号論は、まぁわかるんだが。
そんな俺様にお勧めのHaskell文献があったら教えてください。
Haskell文献?それって言語解説書?
テンプレにあると思うが。
337 :
334:2006/12/20(水) 02:01:53
>335
ごめん。言語解説書ではなくて、背景の理論のほう。
とりあえず俺の勉強したなけなしの記号論理学が
どこをどう通ったらHaskellになるのか見てみたい。
>>337 まず、歴史的にはMLの方が先だから、MLから入ってみたら?
>>337 PierceのTAPLでも嫁
それが理解できなければどうせその先も理解できない
HASKELLってほんとに綺麗だよね。
いつかみんながHASKELLを使う世の中がきたらいいな。
341 :
デフォルトの名無しさん:2006/12/20(水) 07:31:12
ひとつお聞きしたいのですが、
Haskellerで元Lisperの方ってどれくらいいるんでしょうか?
元Lisperの方でHaskellに移ってきた方は、Haskellのどのあたりに惹かれました?
LISPはスーパーな人が沢山いて、敵う気がしなかった。
Haskellはまだ大半が素人みたいなので鞍替えした。
>>341 Haskellを知っている人ならほぼ確実にLispも知ってるよ。
俺 Lisp は知ってるけど Lisper じゃないな
言語の違いでプログラマが変わるわけでもあるまい
用途によっていくつかの言語使い分けるから、何々erではないな
>>337 Haskel は全く知らんけど、その記号論理学とはあまり関係無いんじゃないか?
Lisper 以外の大半人たちは高階の理論を記述する際に階によって用語を使い分ける。
ので集合とか射とか群とか圏とかいろんな言葉が出てくるわけだけど、
やってることはλと(暗黙の)括弧が多いか少ないか程度の違いのような気がするので、
そう大上段に構えるほどの物じゃないような・・・
あまたあるプログラミング言語の一つ
>>341 9割が両刀
1割は悪い人にだまされて最初の言語がHaskellというケース
Lispを最初にやってたほうがいいんかな?
Haskellだけでも十分おもしろいけど。
>>349 C++からLispを経由せずにHaskellをやりだした者ですが、
私をだました悪い人はどこですか?
Javaだけなんとかギリギリできるけど
Haskellも勉強してるよ
オブジェクト指向しか知らない世代なわけだけど
そこに固まらないうちに関数型も慣れときたいなぁと思って
先輩が Lisper で、静的型と動的型の違いを勉強するために Haskell も合わせて
勉強するように言われました。
>>350 関数型言語習い始めだと、副作用なしというプログラミングスタイルは辛いと思う。
まずは副作用ありの関数型言語で慣れておくと良いと思う。
>関数型言語習い始めだと、副作用なしというプログラミングスタイルは辛いと思う。
議論することじゃないが、俺はそうは思わない、という意見だけ表明しておく。
356 :
ド素人:2006/12/21(木) 02:53:37
盛り上がってるとこ悪いんだけどくだらない質問
精製されたexeファイルをGHC入れてない人に実行させるにはどうすりゃいいの?
main = print $ map square [2, 5, 3, 1, 10]
square n = n * n
たとえば↑みたいなプログラムをexeにしたって実行できないよね?
どういうのならできるんだ???
357 :
デフォルトの名無しさん:2006/12/21(木) 02:54:35
Lisp出来る人から見てHaskellの優れてるとこってどこ?
逆にLispのほうが優れてると思うところは?
>>356 問題なく実行できる。
exeファイルをダブルクリックしたけど一瞬だけコマンドプロンプトが開いてすぐに閉じたから実行できなかったと思ったんじゃないの?
それだったらgetCharでも付けて入力待ちさせりゃいい。
main = do { print $ map square [2, 5, 3, 1, 10]; getChar }
square n = n * n
低レベルな質問2
main = do cs getContents
putStr cs
exeファイルにしてコマンドプロンプトで下のように実行しようとしてもできない
ghc out.hs -o out
out 引数(文字列)
なんで?
ふつうのHaskellプログラミングには
実行するには Ctrl - Z + Enter って書いてるけど、これどういう意味?
>>359 そのぷろぐらむだと引数は関係ない。
outを実行すると入力待ちになるから、適当な文字列を何行かタイプする。
入力を終了したくなったら、まず、カーソルが行頭にある状態で
Ctrlとzを同時押しして(^Zという表示が現れるはず)、
つぎにEnterキーを押せば良い。
>>357 どっちもイイね。
Haskell の優れてるところ: 型システムによる安心感、純粋関数型なところ
Lisp の優れてるところ: マルチパラダイムなところ、あんま理屈とか考えずに言語を気軽にカスタマイズできるところ
>>361 Haskellの優れているところ:遅延評価、モナド
Haskellの劣っているところ:遅延評価、モナド
遅延評価は言語の進化過程で最新の部類だぞ・・
モナド(というかdo記法)大好き。
優れているかは別として、Haskellでいちばん好きな機能かも。
なにが遅延評価だ
ここはもうビチョビチョじゃねーか
>>367 doは>>=を使うよりも見栄え良く書けるが、
代入型言語の特徴を残す記法なので、
不満に思う人も多いと思う。
>>369 似たような意見をwebで時々見掛けるが、よく理解できない。
命令的プログラミングをしたいとき、それに適した構文を
使えるのだから、単純に良いことのように思える。
それとも、命令的プログラミングをサポートしない言語の方が
良いという考えなんだろうか。
>>370 「関数」で統一された世界を作れば、何か良いことがあるに違いない
(古風な言い方である自動プログラミング、とか、構造の視覚化がしやすくなる、とか、etc..)
と思う人が多いからじゃないかな?
自分はどするよりコンビネータでモナモナする方がいいな。
どするって流行らせたいの?w
>>=は横に長くなっちゃうのがいまいちだけど、見た目がかっこいいからついつい使ってしまう
do {
a <- hoge;
hoge2 a;
hoge3 a
}
と
hoge >>=
\a ->
hoge2 a >>
hoge3 a
どっちがみやすいですか?
377 :
352:2006/12/27(水) 01:44:38
>>372 この記事おもしろいねw
真実だとしても、結局のところ今はPCの性能の上昇とか
言語自体の進化によってオブジェクト指向は機能的で合理的な言語になってるよね?
たしかに、
「あるプロジェクトのコードを再利用した話なんて聞いたことない」とか、
「正しく継承させるためには設計だけでCの3倍もの時間かかる」とか、
超笑えるねw
当たり前に思ってきた(教えられてきた)コトって、
そのまま信じちゃうからこういう記事読むとオラ、ワクワクしてきたぞ
Haskellだと10倍の時間をかけて10分の1の行数ですみます。
数十万行のsoftware開発してきた身からすると
あの内容はあながち冗談に思えなくて泣けてきた。
彼がinterviewであんなこと言うはずは無いだろうけどさ
>>378 チャッチャと書けるようになったらダイブ頭よくなってるかな?
何を創ったかによるだろ
だよなー
もっとHaskeりたいんだけど、やさしく教えてくれるかわいいコいないかな
ギャルにHaskellは引かれるだけ
禁句だ。
アホか
Haskellを教えてくれるギャルを探すんだよ
∩
| |
| |
∧_∧ | | / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
( ´Д`)// < ⊥が返ると思います!
/ / \
/ /| /  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
__| | .| |
\  ̄ ̄ ̄ ̄ ̄ ̄ ̄\
||\ \
||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄
|| || ̄ ̄ ̄ ̄ ̄ ̄ ̄||
.|| ||
正直、Haskellってオサレだと思うんだけどなぁ。
少なくともVBやJavaやってるよりは確実にイケテルよね?
モナドとかラムダとか遅延評価について語るだけでモテモテな世の中になればいいのに。
HaskellとConcurrent Cleanはオサレ言語だと思う。思いたい。思わせろ。
普段は泥臭いPerl使ってる俺は死んだらいい。
オサレって言葉はいつから誉め言葉になったんだ?
俺的な言語の分類。主観のみで書いたので脊髄反射は厳禁w
■オサレ言語
Haskell、Clear、その他の純粋関数型言語
■普通の言語
C、C++、C#、アセンブラ、PHP、Perl、awk
■キモい・胡散臭い
Ruby(特にRails界隈)、Ajax、XML、Paython、その他Web2.0に絡む言語すべて
■オッサン専用
COBOL、FORTRAN、PASCAL
■厨言語
Java、VB、BASIC、HSP
lispわー?
>390を勝手に書き換えてみる
■オサレ言語
Haskell、Concurrent Clean、その他の純粋関数型言語
■普通の言語
C++、C#、Java、VB.NET
■泥臭い
Perl
■ハッカー専用
C、アセンブラ、awk、Python
■キモい・胡散臭い
PHP、Ruby
■オッサン専用・過去の遺物
COBOL、FORTRAN、PASCAL
■厨言語
VB、BASIC、HSP、Delphi
■宗教
Lisp、その他Lisp系統
393 :
デフォルトの名無しさん:2006/12/31(日) 01:06:40
coolLang = [Lisp, Scheme] :: [Language]
(set! coolLang (cdr coolLang))
395 :
デフォルトの名無しさん:2006/12/31(日) 09:30:38
最近になって Haskell を触り始めたんだけど、
C で言う != みたいな記号ってないん?
環境は WinHugs 使ってる。
>>395 (!=) :: Eq a => a -> a -> Bool
(!=) = (/=)
Rails は確かに胡散臭い
あと perl はなにげにハッカー言語だと思う
>>398 ハッカーが「つくっている」≠ ハッカー言語
いや、ハッカーが使う言語ってのは泥臭いものだよ
そう言う意味で C やアセンブラは納得できるけど Python はどうかなぁ
Haskellって日本語を表示させたりは出来ないんでしょうか?
main = putStrLn "こんにちは!"ってやるとエラーになるんですけれど・・・
あきらめるしかないんでしょうか?
403 :
デフォルトの名無しさん:2006/12/31(日) 22:24:01
GHC 6.6 で部分的に UTF-8 に対応したみたいだけど、
putStrLn とかはまだ未対応みたいね。
日本語を出力できないのかよ!って思ったけど、プログラムにべた書きしてある場合がだめなのね。
408 :
402:2007/01/02(火) 00:02:38
みなさん、ご返答有難うございます。
>>405 ネイティブなバイナリを作りたいんです。
>>406 標準入力から入力した文字を処理させたいんです。
出来るでしょうか?
>>407 windowsマシンしか持ってないんです・・・
> 標準入力から入力した文字を処理させたいんです。
ただのバイト列としての扱いになるけど一応読み込めて表示できる。
なんか混乱気味だなぁ。
GHC6.4ではEUCだったらソースコード中に書いてもコンパイル可能。
putStrなどで出力するとEUCのまま出力される。
そのため、WindowsではEUC→ShiftJIS変換を掛けた後putStrしないとうまく表示できなかった。
GHC6.6ではソースコードの文字コードがUTF-8になったため、
UTF-8形式でなら日本語の文字列をソースコードに記述できるようになった。
しかし、putStrなどのIOの基本部分はまだきちんとUTF-8対応してないため、
UTF-8形式の文字列をそのまま出力させることができない。
ただ、6.4のときと同じようにUTF-8→ShiftJIS変換して出力させるのなら表示できる。
410が紹介しているライブラリはそう言った処理を行ってくれる。
この問題はややこしいし、よく出てくるから、テンプレに入れるのがいいと思う。
間違ってるところがあったら指摘してほしい。
Haskell98によると、Charは一つのUnicode文字を表す(6.1.2)。
これに従って、比較的新しいHugsやGHC(6.4系を含む)ではCharは32ビット整数になっている。
ただし、どちらも入出力に際しての変換が完全でない。具体的には、
・ソースコード中の文字列リテラル
・System.IOライブラリでの入出力
が問題になる。
1. GHC6.4.2以前
ソースコード・入出力ともLatin-1を仮定する。Latin-1ではバイト値と
コードポイントが一致するので、入力時には外部エンコードの各バイトがそのままCharに
入り、出力時にはCharの下位8ビットのみが出力されるような実装になっている。
このため、あるエンコーディング(Latin-1とは限らない)の入力をgetLineで受け取り、
それをそのままputStrで表示すれば、入力時とおなじエンコードにおいて正しく表示される。
これを利用して、[Char]を、本来のコードポイントの列としてではなく、特定のエンコードの下での
バイト列として使うことができる。ただし文字列リテラルについては、GHCはLatin-1として
不正な文字を受け付けないので、EUC-JPのような例外を除くと、単純にリテラルを使うことはできない。
2. GHC6.6
ソースコードにはUTF-8、入出力にはLatin-1を仮定する。このため、EUC-JPでリテラルを直に
書くことはできない。
(続く)
(続き)
3.最近のHugs(非WindowsかつCのwchar_tがUnicodeの環境、というかLinux)
ソースコード・入出力ともロケールのエンコードを利用する。
4.最近のHugs(Windows)
ソースコード・入出力ともLatin-1を仮定する。ただし文字列リテラルにShift-JISを使ってもエラーにならない。
5.最近のHugs(それ以外)
未調査。
・結局どうするか。
規格どおりにCharにUnicodeを入れるか、Charを単なるバイトとして扱うかの二択。
i. CharをUnicodeとして扱う
(3)以外の場合入出力で変換が必要。(2)または(3)以外の場合文字列リテラルでは
明示的なエスケープ(たとえば"\22234")が必要。
ii. Charをバイトとして扱う
(3)ではファイルをバイナリモードで開くなどの対策が必要。(1)でEUC-JPを使う場合と(4)
を除き文字列リテラルでは明示的なエスケープ(たとえば"\143\153")が必要。
lengthやisAlphaのような関数、およびwin32パッケージの関数(win32API)が正しく動作しない。
お前ら、開発に加わって連中に国際化を教えてやってください
ずーっと昔のemacsとかXwindow systemみたいだねぇ。
GHCのコアな開発者(少なくともSimon Marlow)は問題を理解してるよ。
問題はむしろSystem.IOを書き直すのが(重要度の割には)面倒だ、というところに
あるんじゃないかと。
質問です。
1関数とアクションは何が違うのでしょうか?
2square n = n*n
というのはnを引数とする関数を定義しているんですよね。
cみたいにn = n*nという代入を表しているんじゃないですよね?(説明が難しい)
>>418 1. アクションとはIO aを返す関数のことです
2. まずは、squareの型を見てみましょう。
square :: Num a => a -> a
ということですから、代入ではありません。
"IO a"は型ね。
1. アクションは副作用を含むことのできる一連の処理を値(IO a 型)として返す関数。
main 関数の返す値が最終的に実行される。
Perl や JavaScript で、プログラムを内部的に文字列として生成して、
最後に eval で実行するような状況に少し似てる。
2. 関数 square n と n*n とが等値であることを定義しているだけ。
数学では = ってのは左辺と右辺が等しいことを表すよね。
x + 2y = 4 とか、f(x) = 2x + 1 とか。あれと同じ。
>>419 >アクションとはIO aを返す関数のことです
アクション(動作)はIO a型の値のことじゃないか?
たとえばputStrは文字列を取って動作を返す関数。
putStr "Hello"は動作。
>>422 プログラミング指向の論文を読んでいると、
引数または返値に"IO a"を含むものをfunctionとは呼ばずにactionと呼んでいる事が多いので、
そう書いたんだよ。
皆さん回答有難うございます。
代入ではないんですね。
どうも混乱してしまって・・・
cでいう
# include <stdio.h>
int main (void)
{
int y = 0;
y = sqare(3);
printf("%d\n",y);
}
int sqare (int n)
{
n = n*n;
return n;
}
のn = n*n;とは別なんですよね?
アクションのことはおっしゃってることは良く分からないですけど
IOっていうのが味噌なんですね。
それとcのプログラム、関数宣言してないですけど、許してください。
>>425 意味的には似てるけど、
たとえば、Cではsquare(2)とすれば、それがその場で実行されて4という値として扱われるけど、
Haskellでは(square 2)そのものとして扱います。
まず、IO a -> a という事はできません(IOがいったんくっついたら取り外すことはできないの)ので、
Haskellではmainを評価することで実行されますが、
最終的にはmainまで … -> IO aというのを続けて書いていかないとダメなの。
main関数の型は main :: IO () ですよね。
>>425 square n = n * n
に近い書き方は、
int square(int n) { return n*n; }
だね。
逆に、
int sqare (int n) { n = n*n; return n; }
に近いのは
square n
= let m = n * n
in m
func x = func x
main = do func 1
これ ghc だと通ったんですけど、この場合の func の型は何ですか?
t -> t1
>>422 よく参照されるやさしい Haskell 入門ですら、
関数自身の事を表す事もあれば、値を表す事もあるんだよな。
http://www.sampou.org/haskell/tutorial-j/io.html 例えば、7.1 の最初の文
>各 I/O のアクションはそれぞれ値を返します
は関数自身をアクションと呼んでるように見えるし、
その直後の
>これはアクションを他の値と区別するためです
は値をアクションと呼んでるように見える。
どちらもアクションと呼ぶのか、それともいい加減なだけなのか。
どっちなんだろ?
>>425 square n が n * n と等値。
無意識に square と n の間に理解の区切りを設けてるみたいだけど、
そんなものはないと考えた方がいい。
432 :
425:2007/01/04(木) 16:24:19
うぉー、皆さん回答本当に有難うございます。
square n = n*nは理解できました!
関数squareは仮引数nを一つとる関数で、その本体はn*nという理解でよいんですね。
関数とアクションの違いは、まだ勉強不足で理解は出来ていないですけど、
IOが味噌なのは分かりました。
話は変わりますけど、文字列が文字のリストなんて、HaskellはCみたいですね。
リストと配列は違うよ。
>>433 すいません、配列とリストって何が違うのでしょうか?
調べてみたんですが良く分かりませんでした。
例えば
# include <stdio.h>
int main (void)
{
char *string = { "Hello"};
printf("%c\n",string[2]);
return 0 ;
}
みたいにリストって言うのは、配列とポインタの組み合わせとその操作と思っていたんですけれど
違うのでしょうか?
435 :
デフォルトの名無しさん:2007/01/05(金) 14:27:30
Lisp以前の問題
>>434 Haskellでいうリストは「単方向リンクリスト」のこと。
なんか Haskell 勉強する前に勉強しなきゃいけないことがありそうな感じの人だ
Haskellを勉強するのに配列とリストの違いを知っている必要もないような。
>>434 実際のリストは、こんな感じのデータ構造を
適当につなぎ合わせて作られている。
struct Object {
enum {PAIR, INTEGER, STRING} type;
union {
struct {struct Object *head, *next;} pair;
int integer;
char *string;
} body;
};
>>439 それは余りに違いすぎないか?
型タグはない実装が多いだろうし、その定義だと遅延しない。
リストの中身はイテレータ。
>>441 頭の中のモデルとしてはこれで十分。
っていうか、実装の話をしだしたらキリがないだろ
>>443 わざわざ型タグを含めたObject型を持ち出しているから、実装に忠実な
データ構造を提示しているつもりかと思った。
>頭の中のモデルとしてはこれで十分。
遅延を考慮しないなら十分だろうが、そういう単純化した
モデルとしてなら無駄が多くないか?
struct node
{
void *head;
struct node *tail;
};
で十分だと思うが。
>>444 文字列とかの "本物のデータ" が
どう収まるか説明しないと、
普通はイメージが湧かない思う。
まぁ、その判断は
>>434 に任せるが・・・
どう考えても 444 ので十分
同意 十分
検索が定数時間な連想配列を探していて、GHCのData.HashTableに辿り着いた。
でも何でこれってあちこちIO付きなの?
>>448 なぜData.Mapみたいなインタフェースじゃないか、という疑問なら、効率の問題。
Data.Mapのようなインタフェースだと、配列に操作(たとえばinsert)を施した後、
操作前の配列と操作後の配列の両方を操作しえるので、この二つを別々に
保持しておかないといけない。(ナイーブには毎回コピーをとればよい。
もっと低コストな方法もあるだろうが、いずれにせよオーバーヘッドがある)
実際Data.HashTableのようなIOの絡んだインタフェースなら、
常に最新版しか操作できないので、単純なメモリ上の破壊的操作で実装できる。
なぜSTじゃなくてIOなのかという疑問なら、俺にも判らん。
450 :
448:2007/01/06(土) 23:35:56
>>449 ども。Haskell初学者なので処理系の中の人の気持ちはあまりわからんけど、
破壊的操作を用いて実装すれば実行時効率がよいことは理解できる。ありがとう。
STってのはControl.Monad.STのこと?
GHC付属文書での記述を軽く眺めてみたけど、さぱーりだった…
で、便乗して別の質問。Data.Map的なインタフェースを持つ型について。
その型の変数xがあって、内容を一部変更した値を変数yに格納して、
変数xの内容を完全に破棄したとき、「いつでも全体をコピーしたりはしない」
ことはわりと期待してもよいもの?
リストの質問をした者です。
感謝の言葉が遅くなってしまい申し訳ありません。
>>439,444
実際のコードの提示、有難うございます。
>>435,436,437,438,440,441,442,443,445,446,447
ご助言有難うございます。
リストの事はC言語による最新アルゴリズム辞典という本を買ってきて解決しました。
もうひとつ質問です。
文字のリストと文字列の事についてなのですが、
Haskellではこの二つは全く同じで
ある関数がstringを引数にとるなら文字列として扱われて、
[char]を引数にとるなら、文字のリストとして扱われる、
という理解でよいのでしょうか?(ふつうのHaskell、p68から質問です。)
下位の関数の出力がIOだと上位の関数の出力がIO汚染されてしまうんですけど、
なんとか良いプログラミングスタイルないですか?
IOつかわなければいいとおもうよ
>>451 中身では、
type String = [Char]
ということになってるのかな。
だから、Stringも[Char]も同じ。
下位の関数でIOを返した場合、連鎖的に上位のすべての関数の返値にIOをつけなければならなくなると思うのですが、
そういう場合って、SICPで勧めているプログラミングスタイルだと二度手間になってしまいますよね。
中でやってることが外部に副作用を残さないような処理なら
unsafePerformIOでIOを外しちゃえばいい。
>>455 最初から上位の関数にIOをつけておけば良い。
>>456 たとえば、設定ファイルの読み込みとかの用途だとそれでも良いかもしれないが、
unsafePerformIOだと実行順序が規定されなくなってしまうでしょ?
>>457 すべての関数にIOをつけると、ものすごく再利用しにくくて汚いコードになると思うのですが・・
>>458 全体として実行順序が規定されていなきゃいけない処理なら
IOが必要な部分だからそのままでいいのでは。
>すべての関数にIOをつけると、ものすごく再利用しにくくて汚いコードになると思うのですが・・
ライブラリの関数や、部品としての再利用を目的とした関数なら、
将来にわたって入出力をしないと確信を持って言えることがおおいだろうから、
そういう場合にはIOなしで問題ない。
逆に、部品としての再利用性よりも変更に強いことが求められる部分
(アプリケーションのなかで比較的上位の(mainに近い)部分とか)は、たとえ現時点で入出力が
絡まないとしても、IOをつけておいて損はないと思う。
>>450 >STってのはControl.Monad.STのこと?
そう。IOと同様にメモリ操作のできるモナドだけど、
IOと違って入出力には使えず、その代わりrunSTを使って外せる。
>ことはわりと期待してもよいもの?
なんともいえない。
たとえばtailはコピーを一切しないで実装されてる
(結果のリストと元のリストは完全に共有される)し、
Data.Map.insertの結果も大部分を元のmapと共有する。
一方で、initはリスト全体をコピーするし、Data.Array.Array
ではすべての変更操作ごとに配列全体がコピーされる。
(効率のために、なるべくたくさんの操作を一回にまとめて適用できるようになっているけど)
納得いかないな・・・
モナドより使いやすいものは無いものだろうか。
IOというか、(Monad m) => m aみたいな型を付けておけばOK。
Data.Map の実装はAVL木なので、 insert のタイミングでは rotation が発生しうるけど、たいていの場合はそれほどコピーが発生しない。 Data.IntMap はパトリシア木であまりコピーは発生しない。
Data.Array は書き換えのたびに全体をコピーしている。ただし MArray を使えばモナド操作で一部の書き換えが可能。
リストの init はコピーを発生するが、 ByteString の init は定数時間でコピーを発生させない。
Data.Sequence はそれなりの償却コストがかかる。
というようにデータ構造によってそれぞれ違うから、「ドキュメントを読みなさい」というのが正解。
下位の関数の出力がIOでも、それに fmap で純関数を適用すればいいのでは。
綺麗に書きたいなら Control.Applicative が使えるかもしれない。
プログラムのプロファイルを取りたいんだが、可能?
可能なら、どうやったらよい?
知りたいのは、実行したプログラムのどこにどの程度の処理時間がかかっているか、
各関数は何回評価されたか、ってあたり。トータルじゃなくて内訳を見たい。
>>465 GHCを使ってるなら、-prof -auto-all付きでコンパイルして、
できた実行ファイルを+RTS -p付きで実行すると、
<実行ファイル名>.profというファイルにプロファイル結果が出力される。
詳しくはGHCのユーザガイドを読んでくれ。
>>466,467
thx。
ユーザガイドのまるまる1章がProfilingなのね。
ざっと眺めただけだけど、heap profilingなんかは使い込むと便利そうだ。
まずは書いてもらった基本操作から使ってみるよ。
質問です。
Haskellでは空リストがリストの終わりを表すと聞きました。
では、map関数を使って空リストに関数を適用させることは出来ないのでしょうか?
470 :
デフォルトの名無しさん:2007/01/10(水) 11:11:25
ふつうのHaskell読んでるけどさっぱりわからん。
実際に組みながら覚えるのが良いんだろうけど・・・
自分としては最終的にはモナディウスみたいなゲームを作ってみたいのですが
グラフィックを扱うプログラムって、初心者には敷居が高いんですかね?
初心者がHaskellを覚える為に組むとしたら、どんなものがオススメですか?
抽象的ですみませんが、皆さんがどんなプログラム組んで覚えたかでもよいので教えてください。
>>469 空リストがリストの終わりを表すのではなくて、空がリストの終わりです。
プログラミング的には空リストをリストの終わりとして処理しています。
空に関数を適用できません。
>>470 グラフィックスを扱うのはIO周りの事がよく理解できていれば可能だと思います。
残念ながら日本語で書かれたよい文献はありませんのが、英語で書かれた読みやすい論文ならいくつかあります。
↑の方のレスにいくつか論文が上げられていますね。
各種UNIXコマンドとかがおすすめ。
ゲームプログラミングには Haskell は向いてないと思う。
>469
それくらいやってみりゃいいだろ。なんでいちいち聞くの。
Prelude> map id []
[]
というかなんで出来ないと思うのかがわからん。
>>471 >空に関数を適用できません。
これはひどい。
>>475 だったら空リストじゃなくて空に関数適用するようなHaskellコード書いてミロや!!!!
>>476 あんたの空と空リストの定義がおかしいだけ
空リストは空そのものとして定義される。これは仕様書にもある。
>>471,474
回答有難うございます。
結局空のリストに関数適用はできるという理解でよいのでしょうか?
Prelude> map id []
[]
このidという関数はどういう定義なのでしょうか?
また、
Hugs> map id [[],[],[]]
[[],[],[]]
という事も出来たのですが、この場合map関数は
「空リストのリスト」の最後に空リストがもう一こ上のレベル?で有るから
「空のリストのリスト」は終わりと判断して再帰を終わらせるという理解で良いでしょうか?
>>476 まぁいいから外にでて空を見上げてみろ、今日は良い天気だ、「のどか」って書いてないか?
空(カラ)なのか空(そら)なのか空(=NULL)なのか?定義してくれ。Haskell的に
「外にでてから」だけでは推論に足りないって事か。
「屋外にでて上を見上げて」なら推論可能?
>>478 idとmapの定義は
id :: a -> a
id x = x
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
この定義に従って、
map id [[],[],[]]
=> map id ([] : [[],[]])
=> id [] : map id [[],[]]
=> [] : map id ([] : [[]])
=> [] : (id [] : map id [[]])
=> [] : ( [] : map id ([] : []) )
=> [] : ( [] : ( id [] : map id [] ) )
=> [] : ( [] : ( [] : [] ))
=> [] : ( [] : [[]] )
=> [] : [[], []]
=> [[], [], []]
のように計算される。
>>477 そんな記述はどこにもない。
あるというならどの文献のどのページにあるのか言ってみろ。
個人情報じゃないけど何かあったみたい。
>>482 すみません、
Prelude> map succ [1,2,3]
[2,3,4]
を実行するとちゃんと実行できるんですけど、
Prelude> map succ [[],[],[]]
<interactive>:1:4:
No instance for (Enum [a])
arising from use of `succ' at <interactive>:1:4-7
Probable fix: add an instance declaration for (Enum [a])
In the first argument of `map', namely `succ'
In the definition of `it': it = map succ [[], [], []]
を実行するとあまりうれしくない結果が出てきます。
どうしてですか?[]は何型なのでしょう・・・
[1,2,3]の最後に入っている(という主張の)[]はInt型ですか?
>>431 > square n が n * n と等値。
ええ?!じゃあ、たとえば、
test :: Int -> Int
x * x = test x
ってコンパイル通るんですか?!
>>485 >どうしてですか?[]は何型なのでしょう・・・
結局の所、map succ [[], [], []] = [succ [], succ [], succ []]だから、
そのエラーはsucc []を実行しようとして失敗したってこと。
なんで失敗するかと言えば、succの引数はEnumクラスのインスタンスじゃないとダメなのに
[] は [a]型でEnumクラスのインスタンスではないから。
HugsとかGHCiでは関数とか値の型は :t 〜 って入力すればわかる。
例えば map succ の型を知りたい時は、
Prelude> :t map succ
map succ :: Enum a => [a] -> [a]
>>488 mapsucc :: [Int] -> [Int]
mapsucc lst = map succ lst
試しに、上のようなコードを書いてみました。
mapsucc [1,2,3]
を実行すると、
[2,3,4]
のように表示されました。
ここまでは良いのですが、
mapsucc [[],[],[]]
を実行すると、
<interactive>:1:9:
Couldn't match `Int' against `[a]'
Expected type: Int
Inferred type: [a]
In the list element: []
In the first argument of `mapsucc', namely `[[], [], []]'
と表示されました。
おかしいですよね、これって。
[a]って何ですか?空リストは空じゃなかったんですか?!!!!
mapsucc :: [Int] -> [Int] なんだから mapsucc [[], [], []] の [[], [], []]は[Int]型だと思って評価しようとするんだけど、
[[], [], []] :: [Int] であるためには [] :: Int でないといけない。
だけど[]は[a]であってIntではない。よって型の不一致(Couldn't match `Int' against `[a]')
>>491 空の型は総称的定義されているべきだと思うんですけど。
上のコードでは
mapsucc :: [Int] -> [Int]
のように明示的に書いたので、Int型にインスタンシエイトされるべきですよね?
>>492 > 明示的に書いたので、Int型にインスタンシエイトされるべきですよね?
その理屈でいくと、[] + 1 :: Intとか1 + [] :: Int って書いたら
なんか適当なInt型の値が得られなきゃいけないって事?
>>493 1+[]なんて定義できないよね。そう思うよね?
だから、空は抽象的なものであって、Haskellの仕様では、空リストと空は別ものなのです。
そもそも
>>469 に"Haskellでは空リストがリストの終わりを表す"と言ったヤツが勘違いしていると思う。
おそらく
[1,2,3] = 1 : [2, 3] = 1 : ( 2 : [3] ) = 1 : ( 2 : ( 3 : [] ) )
と分解できるから[]が終端なんだと言ったんだろうけど、
これは単に空リスト[]の先頭に3, 2, 1を順に追加していったものがリスト[1,2,3]だってこと。
もしくは、(有限)リストから先頭を取り除く操作をしていった場合、空リスト[]に行き着いた時点でそれ以上先頭を取り除くことが出来なくなるってこと。
一応終端記号的なものとして空リスト[]があるからリストの終わりを表すというのは間違いでもないか。
ただ、リストの要素として[]がリスト[1,2,3]の終わりに入っていると考えるのは間違い。
ふと思ったんだけど、量子コンピュータができれば、リストだけじゃなくて、本当の集合を扱えるようになるのかな・・・
非決定性TMも実現できるんじゃね?
500 :
469:2007/01/10(水) 22:57:09
皆さん、自分が変な質問したばっかりに申し訳ないです。
>>495 すいません。「Haskellでは空リストがリストの終わりを表す」とは書いてないです。
やさしいHaskellのp36に
「空リストは特別な値で、リストの末尾に現れます」とあります。
で、自分が「C言語の文字列でいうところのヌル文字みたいなものだ」と
勝手に解釈したんです。
で、
「map関数で何かのリストに適当な関数を適用するとき、
リストの終端を判定するとき空リストがあれば、
再帰を打ち切る」んだなと思ったんです。
もし曲解している点があれば、指摘してください。
>>500 Haskellのリストは単方向リスト。
Cの文字列みたいに何らかのターミネータを持つ配列じゃない。
struct LIST{void*value;struct LIST*next;};
Cで言うと(struct LIST*)NULLが空リスト。
要するにHaskellはnextの値が空リストかどうかで終端を判断している。
君はvalueが特殊な値('\0')のときに終端になるのだと勘違いしている。
と、説明書いてみたけど、うーん自分でもこれじゃあ分かりくいな。どうかけばいいだろう。
Cで書くなら
enum Tag { NIL, CONS };
struct Nil { Tag t; };
struct Cons { Tag t; void *head; union List *tail; };
union List { struct Nil nil; struct Cons cons; };
という感じでないか
Haskellのリストはモナドなので、Cで説明するのは骨が折れると思うから、モナドで説明した方が良いと思う。
リストというのは、
Cons → 1
↓
Cons → 2
↓
Nil
というような構造になっていて、Haskellコードではこれを 1:(2:[])
と表現しています。 [] はこの場合の Nil のことを表す記号です。
いちいち 1:(2:(3:(4:[]))) と書くのは面倒なので
[1,2,3,4] と書いてもよくて、これは 1:(2:(3:(4:[]))) と解釈されます。
さて、map f という関数は、関数 f をこの Cons の右側につながった値に
それぞれ適用する関数です。
したがって、上の 1:(2:[]) に map f を適用した結果は
Cons → f 1
↓
Cons → f 2
↓
Nil
となります。
map f を [] に適用するとどうなるかというと、 [] は
Nil
という構造なのでfを適用する値が一個もなく、したがって結果は
Nil
のままです。よって map f [] の結果は [] となります。
ふつうのHaskellと入門Haskell読み終わったくらいなんだけど、
SICPって読んだほうがいい?
>506
最近寝付きが悪いので…
サンクス。さっそく注文する。
この手の専門書は、原書より訳本の方がいいよね?
へんてこな翻訳文体が心地よい眠りに誘うと期待
訳がむごいという人もいるが
よほどスラスラ英語を読めるのでもなければ
そんな訳でも訳の方がマシだと思う。
少なくともSICP程度の訳であれば。
>>509 へんてこなのには違いないんだけど、なんか勝手に訳語作っちゃったり、痛さあふれる訳本です。
訳語って翻訳者が勝手に作るものだと思ってた。
>>512 偉い人が作って、みんながそれが正しいと思って使うようになるんだけど、
誰もその人の訳語を使わないし、そもそも新しい訳語を作れるほど自分は偉いんだ、
と思いこんでる身の程知らずのタコだから痛いんですよ。
514 :
デフォルトの名無しさん:2007/01/12(金) 20:49:23
おまいら静かだけど、もしかして二チャンネル閉鎖騒ぎに参加してるですか?
そんなくだらないことに参加はしないのです。
ただ議論がしたいからここを利用しているだけで、
なくなれば別のところにいくだけです。
516 :
デフォルトの名無しさん:2007/01/12(金) 21:24:32
2chが閉鎖したときのためにHaskellについて議論できるような所ってどこがあるのかな
2chほど便利なコミュニティ+情報収集サイトは消えちゃマジで困る
個人的な立場で言うと、まじめにGoogle無くなるよりも困る
俺としてはわりとどうでもいい。
ただ、専ブラの発明は偉大であると思ったので、
この方式自体は生き残るだろう。
ブログってRSSフィードを出力するのが増えてるけど、
専ブラで読める形式を出力するのってどうね?
とブログスレで提案したんだが、だれも作ろうとしない。
ああ、スレ違い
専用ブラウザってのは2chのダメダメすぎる所を補うために出て来たもんであって、
無くて済むのならない方が良い。絶対に良い。
そうかな
2chを毎日見る人間ってけっこう多いと思うぞ
インターネットと2chが1:1になるくらい
となるとブラウザと2chブラウザはわけて存在したほうがスッキリする
ぐわぁ、どうも
文字
文字列
文字のリスト
文字列のリスト
の実感がイマイチわからねぇ。
関数の引数の型によって、文字のリストが文字列になったりその逆になったり
う〜ん。
あと、質問なんですけれども
多相型と型変数ってどこがちがうのでしょうか?
>>521 オマエ、マチガエテル。
2ch ハ、インターネット ニ フクマレルカラ ソレジャ 2ch シカ リヨウシテイナイコトニナルネ。
2ch ブラウザ ガ アレバ ブラウザ イラナイネ。
集約の関係なんてどうでもいいんだよハゲ
>>522 C言語はchar配列が,いわゆる「文字列」じゃん
Haskellは [Char] が「文字列」
あと多相型を表現する(書き表す?)ために使われるのが型変数でそ
じゃんじゃんでそでそ
>>523 きっとインターネット以外のネットワークを使って2chにアクセスしてるんだよ。
528 :
デフォルトの名無しさん:2007/01/13(土) 10:21:05
navi2chが使えて人がいればよくね?
529 :
デフォルトの名無しさん:2007/01/13(土) 11:26:21
>>522 文字 Char
文字列 [Char]
文字のリスト [Char]
文字列のリスト [[Char]]
530 :
デフォルトの名無しさん:2007/01/13(土) 11:27:01
type String = [Char]
赤い彗星はシャア!
ll ll
l| -‐‐- |l
,イ」_ |ヽ_| l、
/└-.二| ヽ,ゝl
l ,.-ー\/. 、l
| /.__';_..ン、 ビ〜ィ〜ム かがーやーく♪
/ /<二> <二>!゙、
//--─'( _●_)`ーミヘ フラッシュバックに〜ぃ♪
<-''彡、 |∪| 、` ̄ ̄ヽ
/ __ ヽノ Y ̄) |
(___) Y_ノ
\ |
| /\ \
| / ) )
∪ ( \
\_)
ll ll
l| -‐‐- |l
,イ」_ |ヽ_| l、
/└-.二| ヽ,ゝl
l ,.-ー\/. 、l
| /.__';_..ン、 ヤツのかげーー♪
/ /<二> <二>!゙、
//--─'( _●_)`ーミヘ
<-''彡、 |∪| ミ __>
( (/ ヽノ_ |
ヽ/ (___ノ
| /
/ /\ |
( ( ヽ |
/ ) ∪
(_/
_人人人人人人人人人人人人人人人_
> シャア♪ シャア♪ シャア♪ <
 ̄^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
ll ll ll ll ll ll
l| -‐‐- |l __ l| -‐‐- |l __ l| -‐‐- |l __
,イ」_ |ヽ_| l、〈〈〈〈 ヽ ,イ」_ |ヽ_| l、〈〈〈〈 ヽ ,イ」_ |ヽ_| l、〈〈〈〈 ヽ
/└-.二| ヽ,ゝl.〈⊃ } /└-.二| ヽ,ゝl.〈⊃ }./└-.二| ヽ,ゝl.〈⊃ }
l ,.-ー\/. 、l | |. l ,.-ー\/. 、l | | l ,.-ー\/. 、l | |
| /.__';_..ン、! ! | /.__';_..ン、! !| /.__';_..ン、! !
/ /<二> <二>!゙、 // /<二> <二>!゙、 // /<二> <二>!゙、 /
//--─'( _●_)`ーミ /.//--─'( _●_)`ーミ / //--─'( _●_)`ーミ /
<-''彡、 |∪| / <-''彡、 |∪| / <-''彡、 |∪| /
/ __ ヽノ / / __ ヽノ / / __ ヽノ /
(___) / (___) / (___) /
534 :
デフォルトの名無しさん:2007/01/15(月) 22:00:10
ここが噂の関数型言語スレか
廃れてんなぁ
なんかHaskelニュースとかねーのか
語ろう是!
任せ炉!
じゃあ質問。
やさしいHaskellのp107から。
myIf :: Bool -> a -> a -> a
myIf True t e = t
myIf False t e = e
main = do myif (True) (putStrLn "then") (putStrLn "else")
という関数を定義して、このプログラムがthenだけ表示されれば、
アクションputStrLn "elseは評価されていないことが分かります。
とあるんだけれど、何が言いたいのか良く分からん。
このプログラムを実行したら、thenが表示されるのは当たり前じゃないのか?
これのどこが評価に必要な式だけが評価されることの証拠になるんだ?
Cの
if ( True == True){
printf("then\n");
}
printf("else\n");
とどこが違うんだ。
これも、printf("else\n");は評価されて無いぞ。
それともif文を実装した点に意味があるって事?
>>540 int myif(int a, int b, int c) {
return a ? b : c;
}
int main() {
myif(1, printf("true"), printf("false"));
}
>>541 うん、それもわかるよ。
でもそれだって結局ifの言い換えでしょう?
俺が聞きたいのは
main = do myif (True) (putStrLn "then") (putStrLn "else")
でthenが実行されるのは当然で、何がすごいのか分からないんだ。
これと遅延評価の何が関係有るの?
教えて、偉い人。
>>540 Cには「中身が実行されないことがある構文」(ifとか)はあるけど、
「引数が評価されないことがある関数」はない。
例えば、Cでは、
f(4 / 0)
という式は、fがどんな関数であっても零除算でエラーだが、Haskellでは、
f (4 `div` 0)
がエラーになるかどうかはfに依存する。
同様に、三項演算子と同じはたらきをする「関数」はCでは実装できないが、Haskellではできる。
>main = do myif (True) (putStrLn "then") (putStrLn "else")
ややこしいことに、この例に限っていえば、遅延評価は関係ない。
たとえputStrLn "else"が評価されたとしても、それで「else」が出力される訳ではない。
これはHaskellのIOの話で、遅延評価とは別の問題。
だから、遅延評価の話をするときは、ややこしくなるのでIOの例を使わない方が良いと思う。
544 :
デフォルトの名無しさん:2007/01/21(日) 11:09:27
理解もできず、実際にコードのコンパイル・実行をしない奴に説明しても。
[ n | (n,True) <- zip [1,2,3,4,5] [True,False,True,False,False] ]
他のletの中とかならマッチしない時点でエラーが出ると思うのですが
なぜこのやりかたで絞込みができるのでしょうか?
内包表記が特別扱いされてるとか?
>>547 リストはMonadPlusで、内包表記はdo記法の略記。
doの中でマッチングが失敗するとモナドのfailが呼ばれ、リストのfailはmzeroを返すから
その後に続く式が無効化される。
549 :
548:2007/01/22(月) 02:06:48
>>548 Prelude> let hoge = zip [1,2,3,4,5] [True,False,True,True,False]
Prelude> do (n,True) <- hoge; return n
[1,3,4]
Prelude> hoge >>= \(n,True) -> return n
[1*** Exception: <interactive>:1:49-69: Non-exhaustive patterns in lambda
なるほど。特別扱いではあるけどユーザも使えるわけですね。
do記法ってsyntax sugerじゃなかったのね
do P <- E ; REST...
は
E >>= \x -> case x of
P -> do REST...
_ -> fail "message"
の構文糖
>>551 > doの中でマッチングが失敗するとモナドのfailが呼ばれ
というところが構文糖だけじゃないんじゃない?ということだと思う。
すまん、書いてから551をじっくり読んだ orz
Haskell98はdo経由せずにそのまま変換するようになってるな
[ e | p <- l, Q ] =
let ok p = [ e | Q ]
ok _ = []
in concatMap ok l
[ n | (n,True) <- zip [1,2,3,4,5] [True,False,True,False,False] ]
=> let ok (n,True) = [n]; ok _ = [] in concatMap ok (zip [1,2,3,4,5] [True,False,True,False,False])
意味はほぼ一緒だが
>>554 Haskell98ではなくて、GHCではそうだね。
556 :
デフォルトの名無しさん:2007/01/23(火) 15:17:18
update :: Assoc a b -> a -> b -> Assoc a b
update h x v y | x == y = v
| otherwise = lookup h y
という関数の定義に関して、
update :: Assoc a b -> a -> b -> Assoc a b
の第一パラメータとなっている、Assoc a b は、
update h x v y | x == y = v
| otherwise = lookup h y
という実装において、
Assoc a b の a が h に、 b が x に対応しているのでしょうか?
よろしくお願いします。
>>556 type Assoc a b = a -> b
と定義してあると思うので、それを前提にする。
>Assoc a b の a が h に、 b が x に対応しているのでしょうか?
違う。仮引数の型は、
h :: Assoc a b
x :: a
v :: b
y :: a
これは、updateの型をAssocなしで書いてみると分かり易い。
update :: (a -> b) -> a -> b -> a -> b
h x v y
558 :
デフォルトの名無しさん:2007/01/23(火) 19:05:54
>>557 返信ありがとうございます。
>これは、updateの型をAssocなしで書いてみると分かり易い。
>update :: (a -> b) -> a -> b -> a -> b
> h x v y
とのことですが、
update :: Assoc a b -> a -> b -> Assoc a b
という定義には、その
>update :: (a -> b) -> a -> b -> a -> b
> h x v y
↑
にあるような、y に相当するパラメータの指定が、
関数定義に存在していないのが理解できません。
これは何か特殊な仕掛けがあるのでしょうか?
>>558 もっと単純な例を挙げる。
foo :: Int -> String -> Bool
という関数があるとする。これはもちろん二引数関数。
括弧を補って丁寧に書くと、この型は次のようになる。(納得できないならカリー化を復習すべし)
foo :: Int -> (String -> Bool)
ここで(String -> Bool)の部分を別名に置き換えても意味は変わらない。
type StringProp = String -> Bool
foo :: Int -> StringProp
こう書くとfooはいかにも一引数関数だけど、型は最初のfooと変わらない。
よって、実装を書く際は引数を二つ使える。例えば、
foo :: Int -> StringProp
foo n s = length s < n
ついでだが、
>関数定義に存在していないのが理解できません。
「update :: Assoc a b -> a -> b -> Assoc a b」みたいなのは型シグネチャといって、
ふつう定義とはいわないと思う。
Haskellの標準GUIライブラリはどこにありますか?
どこにも。
どこにでも。
564 :
デフォルトの名無しさん:2007/01/23(火) 22:01:08
>>559 >>560 返信ありがとうございます。
理解するに至りました。
どうもありがとうございます。
圏論コミュがありえない展開
どこどこ
どこにも。
どこにでも。
569 :
デフォルトの名無しさん:2007/01/27(土) 22:31:06
ソケットプログラミング(TCPもUDPも、IPv6も(!))したいんだが、
何を使うのがお勧め? GHCの付属モジュールにはないようなのだが。
とりあえず、socatという、STDIOをソケットにつなげるツールを
使ってwrapしてみようかとは思っているのだが。
そもそもHaskellでのネットワークプログラミングが、IOと同じ
要領でいいのかどうかも知らないけど。
どれでも
>>569 >GHCの付属モジュールにはないようなのだが。
Network.Socketじゃだめなのか?
GUIプログラミング(Windows上で)したいんだが、
何を使うのがお勧め? GHCの付属モジュールにはないようなのだが。
Windowsだと一応Graphics.UI.ObjectIOがある。
でも資料がほとんどないねぇ。
GHC用のGUIライブラリってwxHaskell, gtk2hsとかほかにも幾つかあるけど、
2006年中に新バージョンがリリースされたものって1つもないよね。
色んな人がライブラリを作ってたけど、どれも長続きしないね…
サンプル見つけた よくできてる
http://www.haskell.org/ObjectIO/life.html http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/hslibs/object-io/Examples/Life/ import Graphics.UI.ObjectIO
-- ghc hello.hs -package objectio -o hello.exe -optl "-Wl,--subsystem,windows"
main = startIO SDI () (openWindow undefined window) []
window = Window title controls attrs
where
title = "hello world"
attrs = [ WindowClose $ noLS closeProcess, WindowViewDomain dom ]
dom = Rectangle (Point2 0 0) (Point2 480 320)
controls = text :+: button
where
text = TextControl "Hello" [ControlPos (Center, Vector2 0 50)]
button = ButtonControl "World" [pos, onClick]
where
pos = ControlPos (BelowPrev, Vector2 (-20) 20)
onClick = ControlFunction $ noLS closeProcess
577 :
デフォルトの名無しさん:2007/01/29(月) 18:44:30
ObjectIOは一度頓挫したのが引き継がれて、GHC-5.02の時期の更新を最後に
開発が止まってるね。
「GTKへの移植は次期リリースで」っていうのを見て期待してたんだけど。
しかもVS2005を入れてもいいかなーって状況になりつつあって
気づいたらVisual Haskell 0.2が出てるんですが、
依然としてVisual Haskellさんは問題ありありな感じだったりします?
>>578 もちろん、問題ありです。
現状では、Windowsでのプログラミング環境は、meadow + haskell-mode + GHCが一番使いやすいですね。
あーやっぱそうですか
問題のありそな処理系使うほどもっさりIDE好きでもないのでスルーしておきますわ
アリガトウ アリガトウ
>>580 IDE好きでないとのことですが、
IDEならEclipseもHaskellをサポートしているようですよ。
情報ありがと
Eclipseも使う機会無くはないんですが冷静に考えると
haskellで大きいもの書くことがほぼ無いのでテキストエディタとghcで十分な感じです
583 :
デフォルトの名無しさん:2007/01/29(月) 20:31:52
>>583 確かに、eclipseのhaskellプラグインも不完全だと思いました。
たとえば、内部でghciを起動したあと、そのプロセスを殺さずに、新たに内部でghciを起動すると、
前のghciのプロセスがそのまま残ってしまう、とか^^;
あと、xyzzyのhs-modeも試してみましたが、
自動インデント機能がおかしくなる場合があるのを見つけたので、
結局、haskell-modeに落ち着いたわけです。
586 :
デフォルトの名無しさん:2007/01/29(月) 21:01:37
漢は黙ってメモ帳+コマンドプロンプト
hasktagって関数をちゃんと認識してくれないときがあるよね
589 :
デフォルトの名無しさん:2007/01/30(火) 21:56:40
EclipseFPでHaskellのソースを
自動整形するのってどうやるの?
できなかったっけ?
590 :
デフォルトの名無しさん:2007/01/30(火) 23:38:11
hasktagsのコードを見れば分かるが、
すんごい単純なコードだったよ。
ちょっと前の話なのであれだけど。
さいきんC++でHaskellicなプログラムを書こうとして
名前の長さと括弧の多さにorzとなってる。
>>591 C++ではどうがんばってもHaskellっぽく書くのは無理だと思う。
遅延評価ができないから。
>>592 遅延評価ができなくとも、HaskellのリストをC++のイテレータだと思えば
リスト周りくらいはイテレータ間の変換として作れそうと思ったのです。
-- なんだかboostにありそうな気もするけど
boost::iterator_adaptorsってやつ?
smp版のghc(6.6)使ってる人いる?
core2duoのlinux上で試してるんだけど、独立した計算を2つのthreadで同時に
やると、1つずつやるより遅くなってしまう…
main = do
m1 <- newMVar iv
m2 <- newMVar iv
s3 <- takeMVar m1
s4 <- takeMVar m2
t1 <- forkIO (summer m1 80000000)
t2 <- forkIO (summer m2 80000000) -- (1)
s1 <- takeMVar m1 -- (2)
s2 <- takeMVar m2
putStr $ "s1: " ++ (show s1) ++ " s2: " ++ (show s2)
summer m n = if s > 0 then putMVar m s else putMVar m 1
where s = summing n 0 -- summingは0からnまでの和を求める関数
上のcodeだと13秒くらいだが,(1)(2)を入れ替える(つまりthread t1の終了を待ってから
thread t2をはじめる)と、9秒くらいになる。
compile時は-smpをつけて、実行時には+RTS -N2を指定してるんだが…
TemplateHaskellでコメントって扱えないのかな?
{-# NOINLINE hoge #-} を一杯生成したいんだが
598 :
596:2007/02/01(木) 19:57:45
誰かいませんかー?
>>599 どうもです。
一応summing(0からnまでの和を求める関数)も引数をeagerに評価させて
ほとんどメモリを消費しないようにしてるんだけど…
summing 0 a = a
summing n a | n > 0 && a >= 0 = summing (n-1) (a+n)
これでもキャッシュ汚染は起こりますか?
高尚な話題の最中に素人っぽい話で割り込んでごめん。
HaskellのライブラリAPIって、ライブラリのソースから自動生成された
(あまり整理されているとは言えない)ドキュメントしかないの?
Network.Socket の使い方が全くわからず数日間悩んでいるのですが‥‥‥。
例えば receipe 集みたいなサイトご存知でしたら教えてください。
本は「ふつうの〜」しか持ってませんが、網羅的な本があったら
がんばって買ってもいいかも。
「入門Haskell」ならある程度リファレンスになるけど、Networkは無いなあ…
>>601 それしかない。
Network.Socketについていうと、リファレンスにも書いてあるが、
インタフェースはCのAPIそのままだから、そっちを調べるべき。
関数に説明が付いていないのもこれが理由。
キャッシュ汚染ってなーに?
>602-604
ありがとう。Cのsocket APIは理解しているつもりなので、想像はできたの
ですが、なんかHaskellicな書き方に慣れないせいか、もうちょっと手引きの
ようなものがあると楽なんですけどね。
なんとかがんばってみます。対向はとりあえずpythonあたりで作って
テスト環境を作ってみないと‥‥‥
haskellよくわからないけど
あの不親切なドキュメントみながら書いてみた
import Network.Socket
main = putStrLn =<< do
sock <- socket AF_INET Stream 0
addr <- inet_addr "66.249.89.104" >>= \x -> return $ SockAddrInet 80 x
connect sock addr
send sock "GET / HTTP/1.1\nHost: www.google.co.jp\n\n"
recv sock 10000000 >>= \x -> sClose sock >> return x
Network.Socket を利用する理由は?
ふつうにネットワークのクライアントプログラムを書くだけなら、 Network で充分じゃないかな。
それでは無理な細かいところを調整するために Network.Socket はある。
逆に言うと、そういう細かいところの欲求ってのはCレベルのAPIを叩きたいっ
てことなんだから、関数名と型名だけあれば、まあ充分なんじゃない。
使いづらいし、ちょっとわかりづらいってのは同意だが。
Control.Monad.Stateってなくなるの?
代用品は?
(´・ω・`)haskellにおけるキャッシュ汚染ってなんなのさ・・・
>611
Haskellじゃなくて、CPUのキャッシュをコンカレントなスレッドが
奪いあったのではないか、という指摘なんじゃないかと。
正直、core2duoのコアとキャッシュの関係を知らないので
そういうことがおこるかどうかは知らない。普通のSMPで、かつ
スケジューラが十分賢ければ、2つactiveなthreadが走ったら
それぞれのthreadをある程度固定化するようにスケジュールして
くれると思うんだけど。
614 :
611:2007/02/05(月) 13:26:20
>>613 さんくす。そういう問題もあるのか・・・。勉強になりますた。
>596,>600 のプログラムだとワーキングセットが各コアのL1に十分おさまりそうだがな。
とすると、
実はsmp対応になってなかっただけ、ってオチがいちばんありそうだな。
Haskellわけわかんねぇ
まだ8bitのバイト列の書き出しすらできねぇ
俺様の頭は激しく悪いな
つ[fromEnum 'a' => 97]
つ[putStr (map toEnum [104,111,103,101])]
つ[import Bits (.&. .|. xor shiftL shiftR)]
>618
サンクス! さんざん苦労してこんなん書いてみたが馬鹿みたいだったな(笑)
頭固くなってしまったものだ‥‥‥ orz
class MessageElement a where
encode :: a->String
decode :: String->a
data MEWord8 = MEWord8 Word8 deriving (Show, Eq, Ord)
instance MessageElement MEWord8 where
encode (MEWord8 w8) = [(chr $ fromInteger $ toInteger w8)]
decode = MEWord8 . toEnum . ord . head
キミの頭がわたしの200倍は良いことが判った
さぁVBの仕事してくるか・・・
みんな〜 お・ま・ん・こ!
Haskell本二冊がどの本屋でも売れ残っているんだが、どっちがおしゅしゅめ?
ちなみに言語はZ80と6800のマシン語しか知らないよ。もう忘れたけど てへ
目を通してみて特に抵抗を感じないならふつうのHaskellの方がおまんこだと思う。
どっちも似たり寄ったりのクズ本だけど、まだふつうのHaskellの方がマシだな。
2冊とも内容的に不十分なので、結局は生の論文を読むしかないと思う。
でも、はっきり言ってHaskellは流行らないと思うよ。
関数型言語の理論的なもとになっているラムダ計算自体が古くさい理論になりつつあるからね。
分散計算には向いていると思うんだがなぁ。
データフローとか、今やったらいろいろと面白そうなんだが、
なにせ理論がむつかしい上に自分が手続き型にどっぷり首までつかった
人間なのと、自分の頭が悪いためたいしたことができてない。
最近の流行りは? >623
C系言語のみに染まっていた俺の脳みそを叩き潰してくれたのはHaskellです
Haskellはいまだに嫌いだけどたまに触ってるしこのスレも見てる
>>623 内容が不十分というのは同意するけど、論文嫁というのは訳分からん。
Haskell 98 Reportを読めば十分だろ。
俺Haskell使えますよ? とか言いてぇぇぇぇぇぇぇぇ
自分ではある程度書けるけど、できる人のコードは読める(読む)気しねえ…
Haskellがはやらなくてよかった
python使いな俺としては、perlよりは好き。
CとRubyとPythonとPerlの違いなんて微々たるものだろ。無駄に分かれてるだけ。
>>631 そんなことをいったらHaskellとCの違いも微々たるものじゃね?
PythonはLisp
>>627 Haskell98Reportだけでは不十分。
これはC++プログラマがオブジェクト指向の本を読んだりするのと似ている。
GHCもHugsも98以降の拡張がガンガン入ってるしねえ。
しかし、λが古くさいって、計算機のパラダイムが根本から変わったなんて話は聞いた事無いんだが…
>>635 > GHCもHugsも98以降の拡張がガンガン入ってるしねえ。
だね。最近どんどん使われはじめているアローズに付いての記述もないし。
> しかし、λが古くさいって、計算機のパラダイムが根本から変わったなんて話は聞いた事無いんだが…
たとえば、ラムダ計算だけではシームレスにアクションを定義できないし、並列性についても定義できない。
次の仕様改訂はいつなのかな。
>>631 Cにはクロージャが無いからそこに並べるのはちょっとキツい
Java7で関数型が導入するっぽい動きだけど、その辺ハスケラー的にどうなの?
Java9くらいで遅延評価と型推論が導入されたりしないかなー
C# 3.0にはlambda式で型推論が一部入るらしい。
クラスベースのOOPLでlambdaってすごく取って付けみたいな感じ
みんな〜 お・ち・ん・ぽ!
>>622-623 返事ありがとう! お礼にボクのちんぽミルクをお口にあ〜ん。
ふつうのHaskell買って見たよ!アホ用に書かれているので読みやすいにゃん
Lispみたいな言語だにゃ。x:xs は Cons CAR CDR だったのかw
忘れてたけど、漏れ昔Lispを勉強したことがあったんだ。
ただし当時ナイコン族だったので脳内Lisp処理系でしか実行したことがないのだがw
うっひょー
ghcの中間語って、今でもSTGなんでしょうか?
>ふつうのHaskell買って見たよ!アホ用に書かれているので読みやすいにゃん
そうなの?
>>646 やぁ お・ま・ん・こんばんわ 昼だけどw
とりあえず8章まではふんふんと来たが代数的データ型でつまづいた。
モナドは難しいことを避けてくれたので何も説明されてないというかw
Newtype宣言したあと『時が見える』見たいな
ところで P199の
(.)関数の型宣言
(.) :: (b−>c) −> (aー>b) −> (a−>c)
凡例 f.g
の順序はこれでいいの隗?
第一引数がgで第二引数がfになるのけ?
なんかキモいスレだな。
結局日本では学生の暇つぶしにしか使われてないのかこの言語。
鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥
鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥
鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥
鳥鳥烏鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥
鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥
鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥
鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥鳥
烏を探せ
鳥鳥鳥
鳥鳥鳥
鳥鳥鳥
鳥鳥烏
>>650 1秒かからず気づいた俺は天才?
ところで、Javaしかできない低脳初級プログラマなんだけど
『高階関数』について、よくわからないんだ
引数に関数を利用するのが高階関数って考えるのは簡単なことだけど、
例えばJavaだって、引数にメソッドを利用することは可能だよね
class A {
private int value ; //属性
public int getNum() { //メソッド1
return 100;
}
public void setValue( int i ) { //メソッド2
value = i ;
}
public static void main( String args[] ) { //mainメソッド
setValue( getNum() ) ;
System.out.println( value ) ;
}
}
でも、Javaには高階関数なんてないわけだよね?
上に書いたclassAは、setValue( int i )の定義で、引数の中にメソッドを入れることは不可能
それと違ってHaskellは、関数の定義(型の宣言)で引数に関数を入れれる
これが高階関数?
でも結局のところ、Haskellの関数は値になるわけだから、
Javaのメソッドの引数に、メソッド入れるのと何が違うのよって・・・(???)
>>652 たとえば、こういうのはできるかな?
hoge :: Int -> Int -> Int
hoge a b = a + b
hoge2 :: (Int -> Int) -> Int -> Int
hoge2 a b = a b
hoge3 :: Int
hoge3 = hoge2 (hoge 1) 3
>>652 関数を引数にするのはまあいいんだけど、
関数を返す関数も高階関数になる。
>>654 新しいJavaの仕様でクロージャを導入したらしいけど
>>653 とりあえずやってみる
classは省略
class X {
public int hoge( int a, int b ) {
return a + b ;
}
}
できた。
class Y {
public int hoge2( ) {
//abってa*bのこと?
}
}
わからん。
class Z {
public int hoge3(???){}
}
さっぱりわからん
先生わかりません
>>655 去年の12月にJava6がでたばっか
Java7はまだまだ先
クロージャについても、まだ検討段階のはずだけど
int hoge2(function a, int b) { return a(b); }
と思えばだいたい OK。
hoge3 を計算すると次のようになる。
hoge3
= hoge2 (hoge 1) 3 (def. of hoge3)
= (hoge 1) 3 (def. of hoge2)
= 1 + 3 (def. of hoge)
= 4
>>= (hoge 1) 3 (def. of hoge2)
ここは
= hoge (1 3) (def. of hoge2)
のほうがわかりやすいな
わかりやすい じゃなくて、それは間違い。
hoge (1 3) は hoge という関数に (1 3) という値を食わせることに
なるが、(1 3) という値が意味不明なので、正しく評価できない。
>>652 public void setValue( int i ) {
これ、自分で引数にint iって書いてあるように、
実際に渡されているのは、関数じゃなくて返り値のintだお。
>>656 これからJavaを新しく学ぼうとする奴は大変だな。
C++でもJavaでも、流行り出した頃に始めると
情報多いし似たようなことやってる人も多いし学習曲線もなだらかで
その後も放っておいても情報が入ってくるけど、
ある程度成熟してからはじめて勉強するのって大変よね。
>>653 Haskellは興味を持ったばかりで全く読み取れないですが
こんな感じでよろしいでしょうか?
interface A { int f(int a, int b); }
class B { A a; int b;
B(A a, int b) { this.a = a; this.b = b; }
int f(int n) { return a.f(b, n); }
}
public class C {
static int hoge2(B b, int n) { return b.f(n); }
public static void main(String args[]) {
A hoge = new A() {
public int f(int a, int b) { return a + b; }};
B hoge1 = new B(hoge, 1);
int hoge3 = hoge2(hoge1, 3);
System.out.println(hoge3);
}
}
スレ違いっぽくてすみません。
>>663 違う言語だから同じかどうかはっきりとは言えないわけだけど、
意図している記法とは違うと思うよ。
最終的な出力は同じでもね。
>>664 Aを二引数の関数、Bを一引数の関数と見ればかなり良く対応していると思うが。
>>666 何が言いたいのか分からん。
>>653は高階関数と部分適用の実演であって、Haskellでは部分適用を
カリー化を利用して行うのが一般的だからそうしているに過ぎないと思ったが。
その気になれば
>>663をカリー化された形に書き換えられるだろうが、
それに何か意義があるのか?
フレームのきっかけを作ったみたいですみません。
記法はともかく雰囲気があっているか(理解が正しいかどうか)
確かめたかっただけです。
Bのfをinterfaceにしてimplementsすればよりそれっぽかったかな。
669 :
667:2007/02/10(土) 17:55:44
>フレームのきっかけを作った
感情的な攻撃をしたつもりはなかった。
そう見えたのなら謝る。投稿内容は無視してほしい。
670 :
668:2007/02/10(土) 18:41:28
思い過ごしでしたか。議論の邪魔をしてすみませんでした。
書き忘れていましたが 663=668≠652 です。
あとhoge2の型も作らないといけなかったですかね。
>>667 > その気になれば
>>663をカリー化された形に書き換えられるだろうが
Haskellで書かれたコードをJavaで模倣したいのかと思ったんだが、
もしそうなら当然模倣できるところは全部模倣すべきだよ。
型チェックは省略。
public class Main {
public static void main(String[] args) {
System.out.println("hoge3 = " + (Integer)new Hoge3().reduce());
}
}
abstract class Closure {
Stack args;
Closure() { args = new Stack(); }
Closure apply(Object o) { args.push(o); return this; }
abstract Object reduce();
}
class Hoge extends Closure {
Object reduce() { return (Integer)args.get(0) + (Integer)args.get(1); }
}
class Hoge2 extends Closure {
Object reduce() { return ((Closure)args.get(0)).apply(args.get(1)).reduce(); }
}
class Hoge3 extends Closure {
Object reduce() { return new Hoge2().apply(new Hoge().apply(1)).apply(3).reduce(); }
}
Adopting lazy evaluation strategy is left to the reader.
おまんこんばんわ
苦労しながらsin x のテイラー展開の収束性を見るプログラムを書いたw
引数は展開次数nとxなのだが、そのうちの展開次数nだけを[1..10]にマップしたい。
だがその方法が分からんので優しいお方おすえて。
カリーかとやらで第一引数だけをまず展開するんじゃないかと思ったが、うまくいかない。
どこを勘違いしているのかも含めてvipperにも分かるように3行で教えてくれw
module Main (main) where
-- Taylor expansion / Honer's method
sin'' 0 x y = y
sin'' n x y = sin'' (n - 1) x ( 1.0 - x * y / ( (2 * n + 1) * (2 * n) ) )
sin' n x = x * sin'' n (x * x) 1.0
converge_sin n = sin' n 1.0
main = print $ map converge_sin [1..10]
出力
[0.8333333333333334,0.8416666666666667,0.841468253968254,0.8414710097001764,0.84
1470984648068,0.8414709848086585,0.8414709848078937,0.8414709848078965,0.8414709
848078965,0.8414709848078965]
じゃわカリー/~
>>676 converge_sin n という捨て関数を使っているし、角度の引数xはこの中で固定化されている。
それが不満。
Mapすると同時に、角度xもパラメータとして与えたい。
main = print $ map (\n -> sin' n 1) [1..10]
main = print $ map (flip sin' 1) [1..10]
main = print $ map (`sin'` 1) [1..10]
main = print $ map f [1..10]
where
f n = sin' n 1
好きなのをどうぞ。
>>678 x=1 の部分をxのままに残して、最後に与えたかった。
こんな感じか?
module Main (main) where
-- Taylor expansion / Honer's method
sin'' 0 x y = y
sin'' n x y = sin'' (n - 1) x ( 1.0 - x * y / ( (2 * n + 1) * (2 * n) ) )
sin' n x = x * sin'' n (x * x) 1.0
main = print $ (\x -> map (\n -> sin' n x) [1..10] ) 1.0
StateとかIOとかわけわかんねぇ‥‥‥ orz
手続き型に20年安住してしまったので頭固すぎて挫折しそうですパパ。
一定の時間ごとにkeepalive処理(通信)を行いつつサービスをするUDPな
サーバを作るときって、次のどちらが素直な設計になるますか?
ヒント頂けると有り難く。
a: State に全部の通信の状態をくるんでしまい、非同期にkeepaliveする
recvfromあるいはselectでタイムアウト付きのwaitがしたくなる、
が、探しかたが悪いのかやりかたがよくわからない‥‥‥。
b: マルチスレッドで走らせてがんばる
>596のforkIOってオイシイ?
スレッド間での状態の同期ってできるの?
c: そもそもそういう処理をHaskellでやろうと思う方が無茶
d: 俺が馬鹿なだけで、もっと簡単な方法がある
その後軽くググって、beautiful concurrencyなる文書を見つけてみた。
まだレベル1と2の間にの俺にはよくわからない気がするが、明日よんでみよう。
STMってなんじゃらほい。interopの小間使いか(ぉぃ)
流れを読まずに質問。
サブディレクトリの中身も取得するgetDirectoryContentsを書いたのだが
どうもコードに無駄があるように思える。
Haskellらしく簡潔に書くにはどう書いたらいいんだ?
--
module GetRecursiveContents (getRecursiveContents) where
import System.Directory
import Data.List
getRecursiveContents :: FilePath -> IO [FilePath]
getRecursiveContents p = do cs <- getDirectoryContents p
result <- mapM (getRecursiveContents' p) $ filter (not . isSuffixOf ".") cs
return $ concat result
getRecursiveContents' :: FilePath -> FilePath -> IO [FilePath]
getRecursiveContents' p c = do let newPath = mergePath p c
dir <- doesDirectoryExist newPath
if dir then getRecursiveContents newPath
else return [newPath]
mergePath :: FilePath -> String -> FilePath
mergePath a b
| "\\" `isSuffixOf` a = a ++ b
| otherwise = a ++ "\\" ++ b
>>681 bだろ。
同期を取るには二つ方法があって、MVarという古典的な共有変数を使っても良いし、
STMという仕組みでロックなしに共有状態を操作しても良い。
STMはちゃんと使ったことがないけど、たぶん次のような特徴がある。
・MVarでできることはなんでもできる。
・明示的にロックをエミュレートしたりしない限り、デッドロックを気にする必要がない。
・(どの程度か知らないが)遅い。
詳しくは、リファレンスや、そこからたどれる論文を読んでくれ。
あんまり変わらないが
再帰の深さの指定をつける時を考えると、ツリー構造定義する方が早い気がする
import Monad
dirrec :: FilePath -> IO [FilePath]
dirrec p = do
cs <- getDirectoryContents p
let paths = [ p' ++ c | c <- cs, not ("." `isSuffixOf` c) ]
dirps <- mapM doesDirectoryExist paths
zipWithM dive dirps paths
where
p' = addYen p
where
addYen "\\" = "\\"
addYen [c] = c : "\\"
addYen (c:cs) = c : addYen cs
dive False = return
dive True = fmap concat . dirrec
686 :
685:2007/02/12(月) 12:47:59
あ、間違えた
型が合っても動作が違う
(...)
fmap concat $ zipWithM dive dirps paths
(...)
where
dive False p = return [p]
dive True p = dirrec p
".",".."だけを特別扱いすれば良いような気がする。
getRecursiveContents :: FilePath -> IO [FilePath]
getRecursiveContents fp
= getDirectoryContents fp >>= mapM (fx fp) >>= return . concat
where
fx :: FilePath -> FilePath -> IO [FilePath]
fx bp "." = return [bp]
fx bp ".." = return []
fx bp f = do let np = bp ++ ('/':f)
b <- doesDirectoryExist np
if b then getRecursiveContents np
else return [np]
>684
ありがと。
どうせ同期を取るのは数秒に一回〜1秒に数回程度で、別に遅くてもいいから
STM使ってみるよ。ghc6.2では使えないんだよね。
getRecursiveContents :: FilePath -> IO [FilePath]
getRecursiveContents fp = liftM concat $ mapM f =<< getDirectoryContents fp
where
f "." = return []
f ".." = return []
f name = getRecursiveContents path `catch` \e -> return [path]
where
path = fp ++ "/" ++ name
doesDirectoryExistが気持ち悪かったので書き直してみたが、
今度は例外を握りつぶしていて良くない。
「inappropriate type」だけ選択的にcatchするにはどうすれば良いんだろう。
haskell-mode-2.2 がelisp errorになる
691 :
683:2007/02/12(月) 22:38:10
答えてくれた人たちありがとう。
がんばってソース読んでみる。
「あるディレクトリ以下の全てのログファイル
(拡張子固定)をすべて集計」ってのをやりたかったんだが
意外とめんどいコードが要るのな。
どちらかといえばHaskellでやる事じゃないな
言語としては悪くないんだが、ライブラリがね…
>>694俺が何か間違ったことをいったか?
例えば、getDirectoryContentsにもっと短い名前を与え、
ファイルパス操作関数を用意するだけで、
>>683みたいなコードはずいぶん書きやすくなる思うが。
短くして何する関数か名前から推測できなくなったらそれはそれで嫌な気が。
よく使うような関数は用意しといてってのには同意。
>>695思った通り素人だ。
CかJavaのプログラマだろうな。
しかも学生。
推測は当たってたか?
>>695=698
気持ちよく書き込んでいたところすまないね。
ここはそういう話をする所じゃないんだよ。
関数名が長いだとか短いだとか、ハンガリアンがどうのこうの、コメントはこうかきましょうだの、
ここの常連はそういう話はとっくに聞き飽きてるの。
700 :
698:2007/02/13(火) 02:11:06
>>699695 ではない.
必要ない書き込みでスレを無駄に消費しているお前がうざいだけ.
これも無駄なレスではあるが.
お前の無駄な書き込みがこのスレから消えてくれることを切に願う.
>>700> これも無駄なレスではあるが.
わかっていて書かずにはいられないとは、リアル厨房か?
どうせ何も本質を理解していないんだろう?
半年ロムってろよ。
>>694 2chで「素人は引っ込んでろ」って、馬鹿?
むしろ玄人様が学会にでも行けよ。
>>702 興奮してるのと、摩訶不思議な2ch観を持ってるのは十分に伝わってくるけど、
文章全体としては何が言いたいのかさっぱりわからない。
>>690 elispもHaskellもよくわからないけど
haskell-indent.el l.319 の :trype を :type にするとエラーは出なくなった
705 :
693:2007/02/13(火) 18:44:48
>>699 >関数名が長いだとか短いだとか、ハンガリアンがどうのこうの、コメントはこうかきましょうだの、
俺だってソフトウェア工学の話がしたいわけじゃない。
>>691が言っているような単目的のコードを快適に書き散らすには
関数名の長さは重要だと思っているから、そう書いた。
それから、判り難かったかもしれないが、
>>693は
>>692へのレス。
副作用を禁止して型とかの制限機構を入れたLispってことでいいのか?
関数型プログラミングしか出来ない(出来るが非常に回りくどい)関数型言語は
結局生産性悪いと思うんだけどどうだろ
Lisp系みたいなマルチパラダイム言語が一番使いやすいなぁ
708 :
698:2007/02/13(火) 23:48:28
それを言っちゃあお終いよ
>>707 今の段階ではね。
でも、まだ研究が煮詰まってないから何とも言えないな。
ど素人が質問するけど、
Haskellでなんちゃらエンジンみたいなの作る場合、
他の言語と比べてけっこういいもんができるそう?
Haskellでなんちゃらエンジンを作れる人が他の言語でなんちゃらエンジンを作ると良いものができるんじゃない?
言語が違ったぐらいで出来栄えがそんなに変わるかなあ。
とか。
むろんケースバイケースだけども。
>>707 Haskellみたいに関数型と手続き型が普通に使えれば十分だと思ってしまうんだが、
そうでもないものなの?
普通には使えないと思う
ひさしぶりにHaskellをGHCでやってみた
なんでこんなにコンパイル遅いの?
だれのせい?
頭のいい奴がつくってこの出来?
>>715 Cコンパイラと比べてないか?
言語仕様がどれだけ複雑か考えただけでも遅くなるのは当然だろ
なんで当然なのか教えてくれ
直感
無限リストって怖くね?
721 :
デフォルトの名無しさん:2007/02/14(水) 03:57:33
OCamlと比べてもコンパイルが遅いのは遅延評価とかモナドとか型クラスとかのせいですか?
コンパイルの遅さよりもバイナリのでかさの方が問題だ
D は言語仕様複雑だけど速い。
要は、
・ 言語仕様が高速なコンパイルに向いているかどうか
・ 最適化をどのくらいやっているか
・ コンパイラのコードが洗練されているか
とかの問題。
>・ 最適化をどのくらいやっているか
>・ コンパイラのコードが洗練されているか
はともかく
> ・ 言語仕様が高速なコンパイルに向いているかどうか
は、高速なコンパイルができる→機械語との対応が簡単→言語仕様が簡単、
って言わないのかな‥‥
人間にとっての容易な仕様と、コンパイラにとっての容易な仕様は別物、
ってことじゃないかなぁ。
Dの場合、「コンパイラ実装に優しい言語仕様」というのをはっきり掲げてるわけだけど、
それは通常の会話に出てくる「シンプルな言語仕様」というのとは、指しているものが
だいぶ異なっているような気がする・・・。
まあコンパイルなんてふつうは遅いものじゃん。
スクリプト言語みたいに実行できるDが異常
おい、カスども聞いてくれ
ようやくまともにHelloWorldが書けるようになった高卒の俺が
圏論勉強してみっかーと思ってWikipedia読んでみたんだ
http://ja.wikipedia.org/wiki/%E5%9C%8F%E8%AB%96 アホだろこの説明はw
翻訳がおかしいというか、書いてる奴が説明する気ゼロなんだよ
そもそも「圏論」とか書くから難しそうなんだ
「カテゴリー論」にすれば、すっげー簡単そうなイメージになるのに
あと「圏」のページでは「定義域」、「余定義域」とかいう意味不明な用語がでてくるが、
「射」のページでは「ドメイン」、「コドメイン」と翻訳してある
用語を統一してないのはWikipediaの特性上しょうがないけど、
ドメインって訳したほうが100倍イメージしやすいよな
円周率を3とするよりも、3.14として難しくしたほうが、学習上、良いのはわかる
けど、圏論の説明はあまりにもひどすぎる
頭が悪いとしか思えない
ということで、AAで圏論 Coming soon!
数学の専門用語の和訳には数学の文化があって、
「カテゴリー」みたいな一般的な用語であっても、
専門用語と分かるように難しい言葉を当てることが多い。
一方、情報化学では、カタカナのまま使うことが多いので、
その辺、語感に温度差があるように思える。
"Categories for Working Programmers" みたいなのが
あると、なかなか楽しい気はする。
> AAで圏論 Coming soon!
期待してるぜ!
> AAで圏論 Coming soon!
wktk!!
数学用語ってかっこいいよな
VIPPERの俺様がWEBに転がっている情報処理の2006年3月号で
圏論を勉強してやっているのだが、定義4までは理解できるが、
肝心のモナドが出てくる定義5と6が意味不明だ。
天才エスパーが3行で解説してプラトンのイデア界のモナドに俺を接触させろ!おねがい (ぅふ
まずはその定義をここに書くんだ
>>733 3行で説明するのは俺には無理.
まず定義5.これは実際に手を動かすと見えてくるので,
具体例でやるのが良いと思う.以下はその pdf にもある例.
1. リスト函手
・型 A に対し T A は A のリストを作る:
T A = [A]
・関数 f :: A -> B に対し T f :: [A] -> [B] は次の関数を作る:
T f = map f
・μ_X は X 型のリストのリストをならして X 型のリストを作る:
μ_X = concat
・η_X は X 型の値 x からそれだけからなる [X} 型のリスト [x] を作る:
η_X = singleton = (:[])
これらを図に代入して,ちゃんと可換になることを確認するよろし.
こっちも同様に確認するとμ,ηの雰囲気がより分かるかも.
2. Maybe函手
・型 A に対し T A は Maybe A を作る:
T A = Maybe A = Just A | Nothing
・関数 f :: A -> B に対し T f :: Maybe A -> Maybe B は
(T f) (Just a) = Just (f a)
(T f) Nothing = Nothing
・μ_X は Maybe (Maybe X) を Maybe X にする:
μ_X (Just (Just x)) = Just x
μ_X (Just Nothing) = Nothing
μ_X Nothing = Nothing
・η_X は X の値 x を (Just x) にする:
η_X x = Just x
やっと分かった!
drop 5もreverseもnullも自然変換で、
map succやallは自然変換でないと。
前者は構造のみを扱い、後者は要素が絡んでいることを反映しているのか。
これ考えた奴は天才だな。
次に定義6.こっちも具体例が条件を満たすことを確認すると見える.
1. リスト函手.これはありがたみが分かりづらい.
・f* = flatten . map f
2. Maybe函手.
・f* = Just . f
Maybe がこれでハッピーなのは,次の具体例を考えると分かる:
「バッグからアドレス帳を取り出し,
今日誕生日の人を探し,携帯電話を取得する」
これを関数合成で次のように書けるとうれしい:
getPhone . findBornToday . getAddressbook
ただ,各関数の自然な型は
getAddressbook :: Bag -> Maybe Addressboo(もってないかも)
findBornToday :: Addressbook -> Maybe Person(いないかも)
getPhone :: Person -> Maybe Phone(もってないかも)
なので合成ができない.そこで,* を使って
getPhone* . findBornToday* . getAddressbook
と書いてやると型があってハッピー.Haskell ではこれを
getPhone <<= findBornToday <<= getAddressbook
と書けるようになってる.
定義5の可換を具体例で示すことはできた。
が、『μが結合則、ηが恒等元の役割をする』というところがピンとこない。
なにとぞ、悟りの光をお与えください。
「結合則」という意味:
左側の図で上側を通る計算はμを中置記法で書き,
TμT = T と簡約しないでおくと
T T T A --> (TμT) T A --> (TμT)μT A
となる.同様に下側を通る計算は
T T T A --> T (TμT) A --> Tμ(TμT) A
となる.これが(任意の A について)等しいのだから,雰囲気は
(TμT)μT = Tμ(TμT) …代数で言うところの結合則
「恒等元」という意味:
右側の図で左側の三角形の真ん中を通る計算は
ηT = T T と簡約しないでおくと
T A --> ηT A --> ημT A
右側の三角形の真ん中を通る計算は
T A --> Tη A --> Tμη A
これが恒等写像 id_TA に等しいのだから,雰囲気は
ημT = Tμη = T …代数で言うところの恒等元,単位元
>>740 dクス 結合法則のほうは分かったw 中置記法が味噌かよwww
中置記法で書くと確かに結合側に見えるw
麻呂は前置記法で書いていたので、どう見ても結合法則ではなく可換を意味しているようにしか
見えなかったでおじゃるw
恒等元のほうは、まだ分からんw
ηだけで恒等元?? (ημ)で恒等元?
でもサ変と右辺でημとμηでひっくり返っているし
もう3行ばかり解説頼むw
>>741 一般に,二項演算 * に対して e が恒等元であるとは
任意の a に対して e * a = a * e = a を満たすことを言う.
μを中置記法で読めば,最後に出てくる式はこれと同じ.
>>740 凄い! なんかわかった気になる。
そうか、μをfunctor間の演算とみなせばよかったのか。
ところで>738の例で
Maybe functorがf* = Just . f
とあるけど、これでfindBornToday*が
Addressbook -> Maybe Person
から
Maybe Addressbook -> Maybe Person
になるんだろうか?
fをもちあげないといけない気がするんだが…
>>743 そのとおりで,こちらのミス.手抜きをしたのがいけなかった.以下が正しい.
f* (Just x) = Just (f x)
f* Nothing = Nothing
ああまたミス.f* (Just x) = f x,f* Nothing = Nothing.起きたばかりだけど寝てくる.
lispとどっち勉強するか迷ってます
lispよりも強力なのがhaskellってことでいいのでしょうか?
強力というのは最小限の手間で複雑な処理がかけるという意味で
>>746 迷ったなら両方やっとけば。
Lispは風呂敷。なんでもリストでつつんでしまう。良く言えば柔軟。悪くいえば節操がない。
Haskellはディナー用食器セット。テーブルマナーがわかっていれば心地良い。
>>747 >Haskellはディナー用食器セット。テーブルマナーがわかっていれば心地良い。
でも調理は自分で、でも何故かアレルギー反応する人がいるのがおもしろい。
昨日は詳しい人がいたのね。
HaskellのMonadって、実はKleisliの方が近いんじゃないか、と思うんだけど、
何でMonadと呼ばれているんだろう?
(T,η, *)と(M, return, flip (>>=))が対応してるのに対して、(T, η, μ)とは
間接的にしか対応してないのに。Monadなんて使わなければ関連する定義
も1つ減って幸せな気がする。
対象→例えば数字だったり、式だったり、式+式だったり
群 →対象の集まり
圏 →対象と射の集まり
これで認識あってる?
モナドは函手の間の演算だってそういうことですか・・・。
752 :
デフォルトの名無しさん:2007/02/15(木) 22:30:13
>>750 数学の用語としてだったら、群は間違ってる。
群は、可逆な演算の定義された集合の事(厳密な言い方でないけど)。
例えば、整数の集合に足し算と引き算を定義すれば、群である。
圏は一応あってると言っていいと思う。
可逆という言葉がわからん
集合という言葉の定義がわからん
群はモノイドでかつ任意の元に対して逆元が存在するもの。
やっぱりボチボチと圏論わかってきてるひと増えてるんだね。
でも、やっぱりよくわからのだがこれ一体なんの役に立つんだ?
757 :
750:2007/02/15(木) 22:50:04
たぶん、オブジェクト指向のようなものだと思うんだが
>>749 一般にプログラミング上の専門用語は、
「寓意的・即物的」であることが好まれるからだろう。
"Kleisli" なんていう、
どう読めばよいのかも分からない人名をつけるよりも、
"Monad" なんて単語のほうがずっとイメージしやすいしね。
この特徴は、プログラミングが「科学」ではなく、
まさに「工学」であることの証拠のように思える。
ていうか、ここら辺はむしろ「科学」のほうが異常なんだと思う。
発見者(又は、偉大な業績を残した先人達)の学問上の
功績を称えるために、発見したものに対して
その人の名前を冠する、という悪しき慣習のために、
新しい概念に対して本当にふさわしい名前をつけることが
出来てないんだよ。
759 :
756:2007/02/15(木) 22:56:08
>たぶん、オブジェクト指向のようなものだと思うんだが
なるほど。
でも、だとしたらコストが高すぎる。一体どれだけ時間かかるんだ。
ていうか、いい加減コーディングスタイル確立してくれ。
というわけで偉い人がんばってくれ。
>>755 data Set
= Empty
| Pair Set Set
| Union Set
| Infinity
| Replacement Fun Set
| Power Set
こんな感じ?
>>759 確かにHaskellって名前あんまり良くないかも。
>>760 "Haskell" 自体は「専門用語」ではないから桶。
あれは「固有名詞」であって、云わば商品名のようなもの。
どんな名前をつけようが関係ない。
>749 >758
そっか、HaskellのMonadと圏論のMonadは別物だったのか…ちょっと驚き
で、結局 Kleisli って、どう読むの?
クライスリーだそうです。
>>742 dクス!! 定義5までは理解した気がするぉ!(^ω^)v
(T μ η) が (対象 演算子 単位元)か。 しかし対象 T は T 1個だけか?
実は理解してないか?(^ω^;)?
定義6についてはこれからエロ画像見ながら考えるぉ
Tは自己函手だ。
μ、ηは自然変換。
>(T μ η) が (対象 演算子 単位元)か。
モノイドとしてみた場合の話だぉ。
>モノイドとしてみた場合の話だぉ。
モノイドとしてみるならTは集合としてみるべき。
>>756 すごく大雑把に言うと,チューリングマシンや
λ計算などがあったところに,新しい定式化として
圏論に基づくものが現れたという背景がある.
現在,普通のプログラマはチューリングマシンや
λ計算を知らなくても特に問題は起きないけれど,
それと同じようなものだと考えるのが順当だと思う.
(もちろん知ってたほうが良いのは確かだけど,
とりあえず大雑把なところを抑えておけば十分.)
ラーニングコストが高いのは,まだ新しい理論である
ということと,従来の手法よりも数学的に取り扱いやすい
枠組みとして導入されたことがあるので,教育用に
整理されてない現段階では,好きな人がやるものだと
思ったほうがよいと,個人的には思う.
>>764 別物というとちょっと語弊があって,
Kleisli triple と monad は一対一対応するので,
どちらで定義しても「本質的には同じもの」になる.
言い方としては,
Haskellでは monad は Kleisli tripleで定義される
というのが間違いないと思う.
>>771 まだまだ未開拓なのか・・・。
>>772 >Kleisli triple と monad は一対一対応するので,
>どちらで定義しても「本質的には同じもの」になる.
!!ですよね。
...| ̄ ̄ | < この話はいつ終わるのかね?
/:::| ___| ∧∧ ∧∧
/::::_|___|_ ( 。_。). ( 。_。)
||:::::::( ・∀・) /<▽> /<▽>
||::/ <ヽ∞/>\ |::::::;;;;::/ |::::::;;;;::/
||::| <ヽ/>.- | |:と),__」 |:と),__」
_..||::| o o ...|_ξ|:::::::::| .|::::::::|
\ \__(久)__/_\::::::| |:::::::|
.||.i\ 、__ノフ \| |:::::::|
.||ヽ .i\ _ __ ____ __ _.\ |::::::|
.|| ゙ヽ i ハ i ハ i ハ i ハ | し'_つ
.|| ゙|i〜^~^〜^~^〜^~^〜
ほかの面白そうな話が始まったら
main = この話 >> main
いや、この路線でいこう。
おれは、参加できないが。
結局、実際に有用なのはモナドのどの性質なんだ?
射の合成則なのか?
対象に順番に射が作用しているという点で、結合則を利用しているようには見えないんだが?
ちんぷんかんぷんだぜ
python経由でならc++もよべるんですよね?
ごめん,だいぶ長文になった.うざかったらスルーしてくれ.
>>778 「射の合成則」は monad ではなく圏の性質なので
これを落とすと圏論で議論ができなくてうれしくない.
Monad を Kleisli triple (T,η,*) で定義したとき,
どれが利いているのかと言うと「全部そろって意味がある」
という答えになってしまう.
では,どんな意味があるのかというと,標語的に言えば,
「monad は『計算』をモデル化できる構造」
となる.これはもう少し説明すると η, * が実際にどう働くかが
見やすくなるので,せっかくだから Haskell の計算をモデル化してみる.
続き.本当は以下の例は正しい Haskell の計算モデルでないし
定義もいくらか怪しいけれど,イメージということで許していただきたく.
>>778 例として
sqr x = x * x,dup x = 2 * x
という関数を考え,sqr (dup 3) という『計算』を考えてみる.
いわゆる手続き言語ではこの式は
sqr (dup 3) = sqr 6 = 36
と『計算』を次々と『値』に潰していくので
型は常に整合しているんだけど,Haskell では
sqr (dup 3) = (dup 3) * (dup 3) = ...
『計算』そのものを『計算』していく.これは sqr の型を
考えるとちょっと奇妙.だけど monad (T,η,*) を
T:X を「X を返す『計算」にうつす函手
η:『値』をその値を取り続ける『計算』にする自然変換
*:『値』を取る『計算』から『計算』をとる『計算』への変換
と定義してやり,sqr (dup 3) が本当は
sqr* (dup* (η3))
を意味していると思うと,きれいに理解できる.
(この η, * は Kleisli triple の条件を満たしている.
ほかの計算モデルでも η, * は同じような役割を果たすので
Kleisli triple の条件が必要なのが理解できる)
>781
おお、何だか凄そうな人が!
いくつか質問させてください。
(1)
> T:X を「X を返す『計算」にうつす函手
> η:『値』をその値を取り続ける『計算』にする自然変換
> *:『値』を取る『計算』から『計算』をとる『計算』への変換
という定義から、
> この η, * は Kleisli triple の条件を満たしている.
は必ず言えるのでしょうか? 上の定義は型に関してKleisli tripleの条件を満たす+ηが自然変換
ということだと思うのですが、「ηが自然変換」ということからKleisli tripleの3条件が出てくるのでしょうか?
(2)
Kleisli tripleの3つめの条件
g* o f* = (g* o f)*
の直感的な意味はなんでしょう?
(3)
λ計算はCCCで普通に解釈できるのにsqr x = x * x,dup x = 2 * xになると
Kleisli categoryが必要になるのは、名前があるからでしょうか?
>>780-781 Haskellの旦那!ありがとう、かなり理解がすすんだぉ(Vipperなりに)。
>>733の定義6でKleisliトリプレットがモナドを為す事も、そこからKleisliカテゴリをだす事も
示せた(と思う ^ω^;)。
T μ (T μ T) = T μ (T*・T) = T*・(T*・T)
(T μ T)μ T = (T*・T)μ T = (T*・T)*・T
こんな感じで射だけを先に色々合成できるので、遅延評価を記述するのに便利
という風に納得したぉw
sqr* (dup* (η3)) = (sqr* ・ dup)* ・ (η3)
こんな風に使える?みたいな?
(T μ T)
泣き顔に見える
頼むからその記号のそれぞれが何を意味してるのか説明してくれ。
この一連の流れ凄いけどいくつか自作自演しているだろ。
レスポンスがおかしい。
>>782 (1) 普通の計算の定義を採用すると,きちんと証明できる.
(満たさない計算もあるだろうけれど,直感に反する気がする)
ηが自然変換であることは Kleisli triple の条件に含まれている.
(2) 『計算』の合成が,直感と整合することの保証.
右辺が何を意味してるかを考えると,左辺が出る.
(3) その式くらいなら CCC で解釈できるんだけど,それは本当に
「自然」な解釈なの? ということで Kleisli でやることを
考えたそうな.なお,λ計算を monad で解釈するためには,
Kleisli + CCC + 整合性みたいな構造が必要.
ηが自然変換であることも重要なん?
要するに、f : A -> T(B)という型の関数の集まりに対して、それが圏を構成するのに必要な
合成演算子とIdの条件を示した、ってことなのかな。
で、圏を構成すると、合成について閉じることと結合法則は保証されるから嬉しい。
まあ嬉しいが、弱い嬉しさだなあ…。
>>788 技術的には自然変換でないと monad の有用な性質が
成立しないので困る,ということがある.
概念的には自然変換の自然っぷりに関連するんだけど,
ηは『値』を『計算』として解釈しなおすだけなんだから,
それが自然変換にならないわけがない.
というのが自分の持ってるイメージ.
> monadの有用な性質
って結合法則?
なんとなく、自然変換にしとくと、添字を省略した等式変形が出来るというイメージが
>>791 有用な性質はたくさんあって,例えば結合法則を含む性質
として「monad と代数が一対一対応する」という定理がある.
ほかにもいくつもの定理や普遍性が成立する.
もちろん自然変換自体が扱いやすいのもそうですね.
>>785 記号の定義は
>>733に引用されているPDFに書いてある。
ジンマシンが出そうな式だが。
>>785 意味は存在しない。というより意味をつけてしまうとダメだ。
なんのためにモナドにまで抽象化したんだって話になる。
個々のモナド(Maybe,List)とかに落とせば意味はつけられるからそこを考えたほうがいい。
モナドの合成は、Kleisli category上ではどういう操作に対応するの?
>>795 函手 F 上の monad と G 上の monad が与えられたとき,
合成函手 F G 上の monad を構成することが合成に相当する.
合成には複数の方法があることも,全く存在しないこともある.
ListのKleisli tripleが
(T1, η1, *1) = ([], \x->[x], \f->\xs->map f xs)
MaybeのKleisli tripleが
(T2, η2, *2) = (Maybe, Just, \f->\x->case x of { Just v->f v; _-> Nothing })
とすると
ListとMaybeの合成は
(T3, η3, *3) = (T1 . T2, η1 . η2, *1 . *2)
にはなりそうもないね…
手続き型に首まで浸かったVipper様が今晩もやってきましたよ。
Kleisli Triplet に関して、手続き型言語へのアナロジー表現で意味を考えてみた。
総本家カテゴリ: 引数:A (値型) 返り値:B(値型) 関数: f:A→B (値型→値型)
元祖カテゴリ: 引数:A (値型) 返り値:TB(参照型) 関数: f:A→TB (値型→参照型)
↓ 関手 η:Id → T (Idは値型を保つ、Tは参照型を意味する。)
分家1カテゴリ Id: 引数:A(値型) 返り値:TB(参照型) 関数: f:A→TB (値型→参照型)
分家2カテゴリ T: 引数:TA(参照型) 返り値:TB(参照型) 関数: f:TA→TB(参照型→参照型)
次に * は、値型引数の関数を参照型引数の関数に変換する演算子とみなす。
f:A→TB、 f*:TA→TB の意味は、同じ関数fの、それぞれ(値型引数A、参照型返り値TB)
バージョンと(参照型引数TA、参照型返り値TB)バージョンに相当する。
Kleisli Triplet が満たすべき3つの性質の、この表現での意味。
・η*_A = Id_A の意味は、値型引数を参照型にする関手ηの引数の型を、*が参照型にするのだから、
η*_Aは、参照型の引数TAが、そのままになる恒等変換 Id_A
・f* 。η_A = f の意味は、値型引数を参照型引数にして、参照型バージョンの関数に
突っ込んだ結果と、引数が値型のバージョンの関数に突っ込んだ結果が同じになること。
・g* 。f* = (g* 。f)* の意味は、参照型引数バージョンの関数f*,g*を合成するのと、
値型引数バージョンfと参照型引数バージョンの関数g*を合成
した上で、その合成関数の引数を値型から参照型に変えたものは同じ物。
この場合のKleisliカテゴリは、
・対象Cは値型変数と参照型変数
・関数 f は値型引数→参照型返り値、関数 f* は f の参照型引数、参照型返り値バージョン
・恒等写像η_A とは、値型変数を参照型変数へ変える関数。
(ηが関数 f に作用すると、f ⇒ f* の変換をする演算子)
・二つの関数 f と g の合成が、g* 。f になるのは、fが吐くのは参照型の返り値だから
g は参照型の引数をとる g* バージョンでないと困るから。
となる?
これは、アトムを値型、リストを参照型とみなしたリストモナドと等価かな?(^ω^?
monadに依存している時点でHaskellは既に敗北しているよな
liskell キタ━━━━━━(゚∀゚)━━━━━━ !!!!!
>>800 ネタにマジレスいくないとおもうけど
モナドじゃなかったら何を使えばよかったと思う?
>>802 副作用を許す
無駄に副作用をなくすのにこだわりすぎ
副作用のある関数とない関数に別の型を与えるかどうか、と言う話で、
結局、どれだけ細かく型を付けるかによるトレードオフだよな。
俺は別扱いするのがコストに見合うと思うが。
ピュア言語に汚れろというのはナンセンスだろw
OOPL同様ピュアを反面教師としてハイブリッド型が生まれるのだ。
>>805 そういう話じゃない。
藻などを使うのが理想的かどうかってことだろ。
手続き型な人には不自然といわれ
関数型な人には関数的じゃないといわれる
IOモナドの何と不憫なことか
ギリシャ文字フリーキャンペーン中です
ΣをSigmaと書きましょう
Concurrent Clean の一意型はどう思われますか?
ギリシャ文字ってうざいよね
ようやく元の馬鹿スレに戻ってきたなw うれしいぜ
もったいぶった馬鹿よりはマシだな
このスレは正真正銘のHaskeller達で構成されているわけではなくて、
Haskelになんとなく関わっていることで自分が賢くなったと思い込みたい人間が大半だからな。
その事実をはき違えて、スレの流れをHaskell本来のレベルに引き上げてもらっては困る。
モナドが「副作用のある計算」をエミュレートするために
使われることばかり宣伝されるのが,悪影響なんだと思う.
モナドは,副作用どころではなく,もっと広いクラスの計算を
統一的な枠組みで定式化できることが本当の利点だと思うし,
副作用に限定しても,どのような副作用が入るかを厳密に
定式化できる構造を与えられることのほうが大切と思うがなあ.
もと物理屋さんなのですが
圏論って勉強するの大変ですか?
集合論と郡論まではなら勉強したことあります
このスレで聞くってことはプログラミングに関連するところさえ
勉強できればいいってこと? そうなら、まあまあ簡単。
PierceとかBarr,Wellsを読んで、具体的な分野の論文見れば
あっさりと追いつける。分からなかったら辞書的にMacLane。
>>818 こんなところで質問する程度のやる気では無理
>818
その質問に対して現状においてもっとも適切に答えをくれる場所
あるだろ・・・。
>817
IOモナドは他のモナドとちがって
随伴使ったモナドと解すべきなんだと思う。
つまり
普通のモナド: Maybe, List, etc..
随伴で構成されたモナド: IOモナド
IOモナドで全部副作用と名のつくものを一括で処理しているのが
いろいろな鯨飲の元なんだと思う。
IOモナドを役割ごとにもっと分割させないと。
本当にIOモナドはI/Oだけ扱えばいいんだと思う。
×鯨飲
○原因
>>796 函手F上のモナドってなんだ?
あんまりよくわかっていないことを言わないほうがいい。
モナドは函手じゃなくて圏の上で構成される構造だ。
だから「自己」函手なわけだよ。
>あんまりよくわかっていないことを言わないほうがいい。
すまん。訂正。どんどんいってけーーーー。
俺もよくわかってないし。
>>822 > 随伴で構成されたモナド: IOモナド
これってどういう意味?
IO monad = (IO, η, μ)
のIOが、何かの左 or 右随伴になってるってこと?
Listだって集合の左随伴だと思うが…
> Listだって集合の左随伴だと思うが…
集合へのforgetful functorの随伴ね
>>826 モナド (F,η,μ) で,特に F を明示したい場合に "monad over F" という
言い方をすることがあるので,それほど変ではないと思うよ.
「圏論の基礎」と格闘中…
こういう話に追いつけるのはいつになることやら。
>>829 !!!
マジで!ちょっとまてわからん。orz
orz
>>828 あー。早とちり。
>のIOが、何かの左 or 右随伴になってるってこと?
そういう意味じゃない。どういう意味かと聞かれたら
そこを現在勉強中です。
うまく答えれません。正直そんなナチュラルに答え返されるとは思わなかった。
>>833 モナドと随伴は一対一対応する.
(随伴が与えられると,そこからモナドが構成できる.逆に,
任意のモナドに対して,それを構成するような随伴が存在する)
よって IO に対してそれに対応する随伴があるのは当然.
ということを言おうとしてると思って,IO の随伴を求めたけど
全然直感的でないものしか得られなかった.
これって何か解釈あるのかな? 参考文献お願いします.
835 :
833:2007/02/19(月) 22:18:07
ちょっと即興で考えて見ます。
ちょうどそれを考えられる材料がそろってきたので。
期待しないでください。
圏論とチューリングマシンやラムダ論法って、同じ記述力なの?
それともどれかがより大きな記述力があるの?
なんで圏論なのさ?チューリングマシンでは駄目なのかよ!
チューリングがホモだからって差別してんじゃないわよ!
>>831 コンマ圏がマンコ圏に見えて困るでしょ?
>>834 モナドを構成する随伴は一般に複数あってそのうちの一方の端が Eilenberg-Moore の
構成でもう一方の端が Kleisli の構成、だよね。
端というのはある圏の始対象と終対象という意味で。
10年間 -> 10年前
>>839 Haskellにはマクロはない。
Lispのことは良く知らないけど、記述力という点で
Haskellより弱いとは思えない。
手続き型言語の方が記述力は高いもんな
手続き型かどうかは関係なくね?
第一級の関数とかマクロとかパターン照合とかが使えるかどうかが大きいと思う。
>>843 それは記述力とは関係なくて、エラー抑制の効果があるだけ。
記述力ってのは型システム(の緩さ)で決まるのですよ。
その結果、Lispの方がちょっとHaskellよりも記述力が高いのですよ。
でも、多くの場面では、カチカチの型が憑いているメリットの方が大きいと思うけれど。
冷静に考えてみると、動的型言語と同等の力が必要ならいつでも
Data.Dynamicを使える訳で、そうしないのは気持ちの問題に過ぎないのかも。
型安全でないHaskellライブラリなんて寒気がする、とか。
どこでもevalれないと同等とは言いたくないぜ。
メタな要素がまざると、型とか意味論的に都合が悪いのかな
つ hs-plugins
ああ、まあ hs-plugins の eval は IO だから「どこでも」じゃないな
HaskellのevalはIOとして外側の世界に出して行うしかない。
LispのevalはLispの世界で定義されている。
この差は大きいと思う。
動的なプログラムはデバッグきつい。
性的なほうがいいね!
最初はきついかも知れんが、動いていればだんだん滑らかになるよ。
きつい方が気持ちよい
854 :
デフォルトの名無しさん:2007/02/24(土) 00:52:28
>>831 圏論の基礎は数学者向けの基礎なので、
普通の人は違う本を読んだほうがいいらしい。
855 :
デフォルトの名無しさん:2007/02/24(土) 01:58:15
これから初心者の俺が朝まで生Haskellやろうかと思うんだけど
おまえら実況板並みに教えてくれないか?
856 :
855:2007/02/24(土) 06:05:17
終了しますた
855≠856
だってだれもレスくれねーんだもん
バベル見て寝たわ
>>858 夜中の2時にいきなりでレスも糞もねーだろw
VIPじゃねーんだぞwwww
昼間に犯行予告をしとけよ
犯行予告は犯罪だからその教唆も明らかに犯罪ですね。
アスペルガーの馬鹿はすっこんでろ!
∩___∩
|ノ⌒ ⌒ ヽ
/ ●) ●) |
Let's | ( _●_) ミ Haskell♪
彡、 |∪| 、`
/ ヽノ ヽ
/ 人 \\ 彡
⊂´_/ ) ヽ__`⊃
/ 人 (
(_ノ (_)
863 :
デフォルトの名無しさん:2007/03/03(土) 00:14:49
い ま か ら ハ ス ケ る か ら お し え て く れ
なんでも聞きなさい。
よーし、じゃあまだ「ふつうのHaskellプログラミング」で
Map関数までしかすすんでないんだけど、
いきなりWikiつくりはじめちゃうぞーー
はははは 父さん元気な子は大好きだぞー
いやーだってね
基礎を勉強したところでコードは書けるようにならないじゃない
なんか作ろうとしたほうが5倍くらい早くおぼえれる
そうだろ?父さん!
>>868 君が一番上達する方法はしらないから、自由にすればいいよ。
ところでこれWikiの完璧なソースはどこにあんの?
本の丸写しだけは勘弁してほしい
そんなアホなことはしない
日本語よりサンプルコードの方が学習しやすい、って人もいるけど、
Haskellでそれができるとしたら「型」の概念に対して
相当鋭敏な感覚を持ってないとむつかしいような気がする。
javascriptとかだったらなんとなく見よう見まねで動きそうな気もするが。
モナド変換子おもすれー
import Prelude hiding(either)
import Control.Monad.List
both, either :: a -> a -> ListT [] a
both a b = return a `mplus` return b
either a b = lift [a,b]
main = do
-- Both Bill and Mary loves either Martha or John.
print $ runListT $ do
lover <- both "Bill" "Mary"
lovee <- either "Martha" "John"
return $ lover ++ " loves " ++ lovee
-- Either Martha or John is loved by both Bill and Mary.
print $ runListT $ do
lovee <- either "Martha" "John"
lover <- both "Bill" "Mary"
return $ lover ++ " loves " ++ lovee
結論: 自然言語にも副作用があるというのにHaskellときたら(略
> both, either :: a -> a -> ListT [] a
こんな書き方できるの初めて知った
関数言語むつかしいよ
こういうプログラムをつくってみようと思い立ってもまったく書けない
あれ?文法どうだったっけ?みたいな
>>876 手続き型言語で培った慣れが役に立ちにくいというだけであって、
学習の難しさはさほど変わらないんじゃなかろうか。
初めてプログラミングを習った人は大抵、
「思い立っても全く書けない」状態を経験するだろう。
Haskellに限ればリスト覚えたら大体何とかなる希ガス
そんなおれになんか課題だしてくれないか
ふつうのHaskellプログラミングでMAP関数のとこまでは読んだ
880 :
839:2007/03/07(水) 21:28:52
lispちょっと勉強してきました
cのプリプロセッサを強引に前処理としてかませば
lispのマクロと同じことができるかも
どういう勉強をどれくらいしたのかは知らないけど、lispのマクロについてもっと勉強した方がいいよ。
>>879 テキストファイルの各行を30文字に切り詰めるプログラム。
>>880 Cプリプロセッサは実質的にチューリング完全だから能力は十分だけど、
Haskellの方がメタなことをするのに適していないような気がする。
例えば、局所的に型を宣言することができないとか。
880じゃないけど
>Cプリプロセッサは実質的にチューリング完全だから能力は十分
これってホント?ループがかけないような
局所的に型を宣言?ってどゆこと?
自己includeでループはできそう。
なるほど、define,ifdefとか組み合わせたらいけそうだな、納得
881です。CPPがチューリング完全だとは知らなかった。その点は謝りたいと思います。
ところで、どうもまだ混乱しているんですが、自己includeのループをどう止
めたものかがわりません。 ifdef とかで何とかなるもんなの? define の再
定義では上手く行かないと思うんだけど。
たとえば階乗を計算するコードって、どんな概形になりますか?
# スレ違いすぎ?
BOOST_PP
でループはできる
890 :
839:2007/03/07(水) 23:55:48
>>888 適当だけどこんなん用意して
#include<boost/preprocessor/slot/slot.hpp>
#ifdef N
#define BOOST_PP_VALUE N
#include BOOST_PP_ASSIGN_SLOT(1)
#define BOOST_PP_VALUE 1
#include BOOST_PP_ASSIGN_SLOT(2)
#undef N
#endif
#if BOOST_PP_SLOT(1) == 0
#define X BOOST_PP_SLOT(2)
#else
#define BOOST_PP_VALUE BOOST_PP_SLOT(2)*BOOST_PP_SLOT(1)
#include BOOST_PP_ASSIGN_SLOT(2)
#define BOOST_PP_VALUE BOOST_PP_SLOT(1)-1
#include BOOST_PP_ASSIGN_SLOT(1)
#include __FILE__
#endif
こんな風に呼び出す。
#define N 6
#include "fact.c"
main(){
printf("%d\n",X);
}
あとはC++関係のスレで
893 :
879じゃない:2007/03/08(木) 01:49:32
>>882 できました!
でも、IOモナドはいまいちピンと来てないです。
あと、全部メモリに読み込んでから処理するのはいいんでしょうか(関数型だとそれがキレイ?)
import System.IO
import System.Environment
main = do args <- getArgs
hFile <- openFile (head args) ReadMode
content <- hGetContents hFile
putStr $ unlines $ map (take 30) $ lines content
最後の行を
mapM (putStrLn . (take 30)) $ lines content
にしてもいけました。
ツッコミお願いします
>>893 お疲れさん。
>あと、全部メモリに読み込んでから処理するのはいいんでしょうか(関数型だとそれがキレイ?)
hGetContentsは全部メモリに読んでる訳じゃなく、入力は遅延する。
これはこれで気持ち悪い(副作用と紙一重)けど、便利なことは間違いない。
単に読み込み専用で開けて読み込むだけならreadFileで良いと思う。
import System
main=getArgs>>=readFile.head>>=mapM_ putStrLn.take 30.lines
896 :
893:2007/03/08(木) 02:25:45
>>894 ありがとうございます!
Stringの値が必要になったら全読みされちゃわないんですか?
Stringのケツが必要になるまでは遅延される?
>>895 1行キタ─(゚∀゚)─!!!! まさに関数型!!!
関数合成ってそう使うんですね。初めてしっくり来ました。
897 :
893:2007/03/08(木) 02:55:18
おっとトラップ?
main=getArgs>>=readFile.head>>=(\c->mapM_ (putStrLn.take 30)$lines c)
にしないと、
>>882の動きになりませんでした。
このラムダは消せないのでしょうか…?
自分なら
main = getArgs>>=readFile.head>>=putStrLn.unlines.map (take 30).lines
とやる。
>>897 main = getArgs >>= readFile . head >>= mapM_ (putStrLn . take 30) . lines
ちょっと分かりづらいか・・・。
#includeで実現できるのはスタックにすぎない
よって実現できるのはプッシュダウンオートマトンであってTuring機械ではない
(外部スクリプトで複数回CPPをかけていいんならTuring完全になる)
ただしC++ templeteを使っていいならTuring完全になる
901 :
839:2007/03/08(木) 09:37:55
言語同士にはそんな単純に言い切れるほどはっきりとした差がつくもんじゃないよ
おもちゃベンチマークでもなければね
どうして安易な1フレーズの結論に飛びつきたがるのかなぁ
>891
Boost だけど template を使ってるわけじゃないんだね。
漠然と、シンボルを結合したりしているのかな、とは思っていたが、うまい方法が思いつかなかったよ。ありがとう。
>>899 最後は、mapM_の部分適用…と思って、小一時間悩みました。
最後は、(mapM_ (putStrLn . take 30)) . lines と評価されるんですね。
結合順位重要。関数適用最強…と。 _〆(。。)
GHC使いなら -ddump-parsed をつけてコンパイルしてみるのも手かと。
908 :
デフォルトの名無しさん:2007/03/08(木) 23:48:49
ちょっとやってみたけど
まぁまぁ面白いな
main = readLn >>= print . (1+)
を -ddump-parsed つけてコンパイルしてみたら(GHC6.6)
==================== Parser ====================
main = (readLn >>= print) . ((1 +))
って表示されたんだが、このパースは間違ってる。
実際、これをコンパイルすると型のミスマッチのエラーが起きるし。
本来は
main = readLn >>= (print . (1 +))
とパースされるわけで、実際処理系自体はそのようにパースしてるはず。
結合の弱い順に演算子を使った
main = a >> b || c && d == e : f + g * h ^ i . j
に対しては
main = ((((((((a >> b) || c) && d) == e) : f) + g) * h) ^ i) . j
となった。どうも、演算子の結合強度を全く考慮していないらしい。
といっても、演算子の結合強度はパースしてみないと分からないので仕方ない。
代わりに-ddump-rnを使えば良さそう。
913 :
907:2007/03/09(金) 17:16:48
>>912 あー、ほんとだ。こっちの方が正しいね。サンクス。
main = writeFile "a.txt" "こんにちは"
GHC 6.6 Windows環境で上記ソースをUTF-8にして実行してみたんですが、
出力ファイル(a.txt)の中身が「S?kao」となってしまいます。
日本語を正しく出力するにはどうすればいいんでしょう?
毛唐に任せてたら対応がいつになるか分かったもんじゃないぜ。
だれか直してパッチ送りつけろ。
918 :
914:2007/03/11(日) 15:47:50
>>915 どもです。IOの標準ライブラリがUTF-8対応されたわけじゃないのですね。
日本語がどうしても必要な時はWinHugs使ってみます。
こちらはこちらでアンインストールできないバグがありますが・・・。
これってWindowsAPIとか呼べますか?
これってどれよ
これっちゃこれよ
importsのしたにSystem.WIn32.*ってあるな。
でもリファレンスには載ってない。System.Posix.*は載ってるのに。
>>917 それは違うんじゃないか?
> * String/ByteString/UTF8String/UTF16String as filename
まあファイル名にも使えて然るべきだけど。
>>923 コード変換が実装されない一番の原因は、今のGHCのIOライブラリが拡張しにくい
構造になっていることだから、それをまずなんとかするのが先決だ。
で、なんとかしようというのが
>>917の提案だろう。
枠組さえできれば、コード変換を実装する事自体は難しくない。
おまえらWindowsでHaskellしてんの?
Linuxの場合、Fedoraはいろいろ対応してるぽいが、
Debian系のUbuntuは使用不可能?
926 :
デフォルトの名無しさん:2007/03/14(水) 02:00:13
>>924 いつのまにか書き換えられてるな。
・Various encodings (UTF8,UTF16...) for text files
もリンク先に増えてる。うしゃ。
しかし、
class Stringable a where
length :: a -> Int
concat :: [a] -> a
....
instance Stringable String
instance Stringable ByteString
instance Stringable UTF8String
instance Stringable UTF16String
なの?個々の文字はどうするんだ?
Charに32ビット使ってるのにUnicode(UCS4)のコードポイントそのまま使うんじゃないの?
つうか、リストじゃないの?そんなのありえるの?
929 :
デフォルトの名無しさん:2007/03/14(水) 19:59:59
Haskellの型推論って中の人どんなふうに動いてんの?
Javaにはそんな機能ないけど、
例えばプリミティブ型もIntegerとかにして、
ぜんぶをObject型で扱えば、なんでも突っ込めるようになるはずだけど、
それとはまったく違う?
>>929 型推論と多相型をごっちゃにしてないか?
型推論は純粋にコンパイル時の操作で、一旦型が推論されたら、
明示的に型を書いた場合と全く同じようにコンパイルされる。
多相型の実装の話なら、その通りで、Javaのオブジェクトと同様あらゆる型をポインタを介して扱っている。
Haskell の日本語の本2冊を一通りみたんだけど、
関数を返す関数が見当たらなかった?ような気がする。
Lisp 等だと普通に lambda を返す様な事をするけど、
Haskell の日本語の本2冊を一通りみたんだけど、
カリー化された関数は作成してるけど、
無名関数を明示的に返す関数は無かったような気がする。
そんなのはあんまり書かないのかな?
>>931 無名関数を明示的に返すくらいなら、最初からカリー化を利用して
引数を導入しておいた方が楽だからじゃないだろうか。
ただし、すでに名前の付いている関数を返すことはときどきある。
f :: Int -> Int -> Int -> Int
f 0 = (+)
f 1 = (-)
f 2 = (*)
とか。これの延長で無名関数を返すこともあるだろう。
f 3 = \x y -> if y == 0 then 0 else div x y
934 :
デフォルトの名無しさん:2007/03/15(木) 00:52:08
>>927 勘違いしてたらスマンけど…。
Stringable aは、Stringable aであって[Char]じゃない
→リストじゃない→リストを扱う関数が使えないのでは?
UTF8Stringとかってエンコーディング処理が隠蔽されてるんだと思うけど、
今のStringの置き換えにするには、単純な[Char]に比べて性能遅そうな気が。
あと、エンコーディング毎に型が別ってのは、正しいのかも知れないけど、
コンパイル後に対応エンコーディングを増やすってどうやるの?
っていうか、ByteStringってエンコーディングは何?
と、疑問が山ほど。
>>934 >Stringable aは、Stringable aであって[Char]じゃない
>→リストじゃない→リストを扱う関数が使えないのでは?
その通り。ただし
toString :: (Stringable a) => a -> String
fromString :: (Stringable a) => String -> a
は簡単に書ける。
>UTF8Stringとかってエンコーディング処理が隠蔽されてるんだと思うけど、
>今のStringの置き換えにするには、単純な[Char]に比べて性能遅そうな気が。
速度が多少犠牲になったとしても、空間効率が[Char]よりずっと良い。
[Char]だとGHCでは一文字あたり約20バイト必要だけど、UTF-8配列なら1〜4バイトで済む。
>あと、エンコーディング毎に型が別ってのは、正しいのかも知れないけど、
>コンパイル後に対応エンコーディングを増やすってどうやるの?
UTF*StringはあくまでStringの代替としての内部コードで、Stringの場合と同様に
入出力時にコード変換する使いかたが想定されているんだと思ったが、ちょっと自信がない。
>っていうか、ByteStringってエンコーディングは何?
本来のByteString(Data.ByteString.ByteString)はWord8の列なのでエンコーディングは関係ない。
ここで問題になってるのはたぶんData.ByteString.Char8.ByteStringで、これはLatin-1。
>[Char]だとGHCでは一文字あたり約20バイト必要だけど、
まじですか。
Charのデータ自体は4バイトだから、
リストノードひとつに16バイトも必要なの?
でも、ポインタひとつ4(or8)バイト食えばそんなもん…か?
>UTF-8配列なら1〜4バイトで済む。
UTF-8なら1〜6バイトではないかと。まあ20バイトの比ではないが。
Stringのcons
enter : 4bytes -- クロージャ進入関数へのポインタ
Char : 4bytes -- headへのポインタ
String : 4bytes -- tailへのポインタ
Char
enter : 4bytes
Char# : 4bytes -- コードポイント値
計20bytes
確かめたわけじゃないけど、これで実測と合う。
>UTF-8なら1〜6バイトではないかと。
Unicodeの範囲(0..0x10ffff)なら4バイト以下で表せる。
>>935 Stringable.hsにはtoString, fromStringじゃなくて、toList, fromListが定義されてるのでわざわざ書く必要すらない。
名前が違うだけで型は全く同じ。
>>934 対応エンコーディングを増やすためには適当なデータ型を用意してStringableクラスのインスタンスにしてやればよい。
おおざっぱにはこんな感じ。
data MyString = MyString ByteString
instance Stringable MyString where
empty = MyString empty
head (MyString bs) = (bsから先頭1文字分取り出してChar型の値にして返す処理)
...
939 :
デフォルトの名無しさん:2007/03/15(木) 13:16:51
> toList, fromListが定義されてるのでわざわざ書く必要すらない。
それはわかるけど、リストで使うときとStringableで使うときで
バンバンそんな変換してたら遅いじゃん?
メモリ節約どころの騒ぎじゃないじゃん?
> 対応エンコーディングを増やすためには適当なデータ型を用意してStringableクラスのインスタンスに
そう言う事じゃなくて、プログラムとして、エンコーディングをpluggableに出来ないじゃんと。
例えば、Stringable を使って作られたエディタが配布されてるとする。
そのエディタに対して、対応エンコーディング追加プラグインみたいのが作れないのでは、という事。
あるいはプラグインでなくてもいい。
そのエディタ作者は英語しか出来ずStringableで書いても、入出力はLatin-1しか考えてない。
で、これを作者が存在すらしらない、SJISString, EUCJPString, Big5String みたいのを扱えるようにするには、
どうすればいいの?毎回ソース書き換えてリコンパイル?
リスト的な操作をするときにいちいちリストに変換してやるわけじゃないんだけど。
mapとかfoldrとかいった操作は効率の良い定義に置き換えることも出来るようになってる。
pluggableに関しては、今のStringable.hsはそういう作りになってないんだから、書き換えてリコンパイルするしかないじゃん。
>それはわかるけど、リストで使うときとStringableで使うときで
>バンバンそんな変換してたら遅いじゃん?
リストとして使いたいなら従来どおりStringを使えば良い。
そのためのinstance Stringable String。
リスト一般用の便利なライブラリと、
Stringable用の便利なライブラリがあるとき、
変換せずに両方混在させて使える?
pluggableは、String以前に、Haskellでそもそも可能なの?
コンパイル時に知らないsubtype(クラスのインスタンス)を、
動的にファーストクラス値で指定してロードってできるんだっけ?
>リスト一般用の便利なライブラリと、
>Stringable用の便利なライブラリがあるとき、
>変換せずに両方混在させて使える?
使える。Stringはリストであると同時にStringableなので。
Haskellは実装の多重継承がokなんだな。
いわゆるダイヤモンド継承問題はどうなってるんだろう?
Haskellに実装の継承に相当する機能なんてあったか?
これが噂のオブ脳
>>943 話の流れからして、StringじゃなくてUTF8Stringとかでそれが出来るかって話だと思うが。
>>947 どこをどう読むとそういう話になるんだ?
ともあれ、UTF8Stringはリストじゃないので、リスト操作関数は使えない。
>>937 クロージャ進入関数って?
データが関数のポインタを保持するの?
結局の所
http://darcs.haskell.org/SoC/fps-soc/Data/Stringable.hs を読めってことになるんだが、
UTF8StringとかのStringableな型ではmap,take,foldrとかのリスト操作的な関数がデフォルト定義として与えられている。
だけどPreludeの同名の関数たちとは型が違うから、単にimport Data.Stringableとすると衝突してしまう。
なので、実際に使う時はimport qualified Data.Stringable as S みたいにして、
Stringable用の関数は S.map, S.take, S.foldr のようにS.を付けて使うことで衝突を回避する。
>>949 Haskellではデータ構造の一部が未評価のことがあり得るので、
評価用の関数ポインタを保持せざるを得ない。
>>950 基本的な関数はStringableクラスにもあるけど、
リストにしか対応していないライブラリも多い(例えばParsecとか)。
「リスト操作関数」という言い方が悪かったか。
952 :
デフォルトの名無しさん:2007/03/16(金) 03:03:53
Parsecが使えない文字列なんて…。
っていうか、Stringableとリストのクラスを作るんだよね?(:)とかheadとかtailとか++とか!!とか。
それでも現行のリスト用ライブラリは使えないけど、じきに対応してくれるのを待つ、と。
でも構文的な問題が厳しいか。
>>952 >Parsecが使えない文字列なんて…。
何を問題視しているのかさっぱり分からん。
従来ファイル名にはStringしか使えなかったのを、Stringableのインスタンスならどれでも
使えるようにしよう、という互換性を保った拡張であって、Stringで満足しているなら
Stringを使いつづければ良いんだが。
Haskell ぼろぼろじゃん
コンストラクタになる関数とパターンマッチで使う逆関数を用意したら既存のdataが拡張できるような仕組みがあればいいのに
遅そうだけど
extendedList :: (a -> b -> b) -> b -> (b -> Maybe (a, b)) -> (b -> [a], [a] -> b)
extendedList cons nil match = (forth, back)
where
forth = unfoldr match
back = foldr cons nil
>>953 非Latain-1 リストベースライブラリでの使用
String × ○
Stringable ○ ×
望まれる物 ○ ○
例えば、(メモリ効率の改善はなくなるが)
バイト列とStringの変換関数だけを提供するという解も有り得るかと。
あるいは、Stringableの方向性でいくなら、
Stringableをリストの「インスタンス」にするか、それが無理なら
リストとStringableを包含したクラスを作って、リストの構文でも扱えるようにすれば、
リストベースライブラリもわずかな修正とリコンパイルだけでStringableでも使用できるようになるのでは?
>>957 ・Stringという型とStringableというクラスを比較するのはおかしくないか?
・Stringでも非Latin-1の文字は使える。
俺ならこういう表にする。
Parsec(リストのみ) 現行IO(Stringのみ) 提案IO(Stringable)
String ○ ○ ○
UTF8String × × ○
[Word8] ○ × ×
>>917のリンク先の提案は、「IO」という縦の列の改善提案であって、
例えばUTF8StringがParsecで使えるかどうかとは関係ない話だと思うが。
「リスト的なコンテナ」を表現する型クラスがあっても良いとは思うけど、
それは少なくとも
>>917とは別の話題だと思う。
とすると、
>>917が
>>914-916とは別の話題だったということか。
それはともかく、
・Haskell(Hugs/GHC)自体は、FPSは関係なく、ちゃんと
CharにUnicodeコードポイントを(1byteずつに分けずにまるごと)入れて、
readFileとかputStrとかが適切にデコード・エンコードしてくれる方向
・FPSは、それとは直交して、
効率の良いString(able)クラスを作ろうとしていて、
エンコーディングも扱う
と理解してOK?
しかし、せっかく作るStringableだが、
Parsecなどのリストベースのライブラリで使えないというのは、勿体ないとは思わない?
リスト派とStringable派にライブラリが分裂しちゃうじゃん。無駄じゃん。
文字エンコーディング機能が、
readFileとかの関数と、Stringableのインスタンスの両方に実装されるのも
DRYじゃないし、テキストを扱う流儀の分裂を招く。
>>959 >とすると、
>>917が
>>914-916とは別の話題だったということか。
いや、
>>917はGHCのIOライブラリを作りなおそうという話であって、Stringableの提案は
その一部に過ぎない。ので全体としては関係あると思う。
>しかし、せっかく作るStringableだが、
>Parsecなどのリストベースのライブラリで使えないというのは、勿体ないとは思わない?
>リスト派とStringable派にライブラリが分裂しちゃうじゃん。無駄じゃん。
確かに。
>文字エンコーディング機能が、
>readFileとかの関数と、Stringableのインスタンスの両方に実装されるのも
>DRYじゃないし、テキストを扱う流儀の分裂を招く。
これは仕方ないような。readFileがやるのは
外部エンコーディング <-> 内部エンコーディング
の変換で、例えばUTF8Stringが行うのは内部エンコーディング間の変換。
962 :
デフォルトの名無しさん:2007/03/17(土) 15:46:20
よくわからんけど
(:)とか[]は
Stringableじゃ使えないのか。
例えばUTF8Stringな s に対して 'a':s みたいなことは出来ない。
964 :
デフォルトの名無しさん:2007/03/17(土) 16:25:48
Stringableとリストを共通クラス化しておかないと、
リストを使った実装群と、Stringableを使った実装群に分断される。
将来絶対、混乱や重複実装の元になって問題になるだろ。どうにかしろよ。
リスト系関数使えないってかなりまぬけだ
はぁ?頭悪い人か
>>946 >>944=Tucker!
C++が最高だと思って相手構わず噛み付く痛い人だから
相手にしなくておk
monadic programming の主旨も理解できてないレベル
>>966 使えるのか?
同名の関数があるってオチは無しだぜ?
> Stringableとリストを共通クラス化しておかないと、
一応リストっぽい操作を持つ型構築子クラスとしてはData.Foldableってのがある。GHC 6.6で追加された。
ただ、これを使ってUTF8StringをFoldableのインスタンスにすることはできない。
なぜならUTF8Stringは型であって型構築子ではないから。
一旦type UTF8String = UTF8StringC Charみたいなものを考えて
UTF8StringCをFoldableのインスタンスにすることは出来るだろうけど、それってどうなんだろう。
型はそれで一応解決?としても、
: と [] は言語仕様の方に手を入れるしか。
[]は単なる糖衣としても、 : は?
>>969 それだと、UTF8StringC Doubleなんていう型を作れることになるな。
まじめにリストをクラス化するとしたらこうだろう。
class List container element | container -> element where
nil :: container
cons :: element -> container -> container
match :: container -> Maybe (element, container)
...
で、
instance List [a] a
instance List UTF8String Char
...
しかし、これってやるに値することなのかな。
型クラスを介して操作するなら、コストの点ではリストに変換してしまうのと大差ないような。
うん、そういう変なのが作れちゃうからどうなんだろうって思った。
> class List container element | container -> element where
関数従属って全然使ったことないから思いつかなかったな。
これはとんだコードは簡潔だけど記述するのに30倍くらい時間のかかる糞言語ですね
>>973 どういうコードを書いているかにもよるが、Haskellじゃなくて
お前が糞である可能性も十分にあると思う。
特に、コードが簡潔なのに書くのに時間がかかる場合、
不慣れなだけな可能性が高いかと。
馬鹿を寄せ付けない言語として最強
馬鹿はJavaでもやってろwwwwww
976 :
デフォルトの名無しさん:2007/03/18(日) 14:36:27
>>971 >型クラスを介して操作するなら、コストの点ではリストに変換してしまうのと大差ないような。
Stringableも型クラスじゃん。違うの?
どうせ型クラスなら、分断と混乱を防いだ方が良いと思うけど。
デフォルト定義をそのまま使うならコストがかかるかも知れないけど、
それぞれの型に最適化した定義で上書きできるからあんまり問題ないと思う。
>>976 >Stringableも型クラスじゃん。違うの?
だから俺は今のままのStringableなら要らないんじゃないかと感じている。
>どうせ型クラスなら、分断と混乱を防いだ方が良いと思うけど。
何か混乱してないか?
*型*が乱立すると確かにまずい。ライブラリAが型Tを使い、
ライブラリBがTと似た型T'を使い、しかもTとT'が相互変換できないなら、
AとBとの間に互換性がない訳で、早急に解決すべき問題だ。
一方、*型クラス*の乱立はそんなに深刻じゃない。
ライブラリAがクラスCを使い、ライブラリBがクラスC'を使ったとしても、
CとC'の両方のインスタンスであるような型Uがあれば、Uを使って
AとBを併用できる。つまり相互運用性が保たれる。
型クラスの乱立はない方が良い(コードの重複を招くので)けど、
できてしまったものはしかたないし、躍起になって防ごうとするほどのものでもないと思う。
例えば、提案通りIOライブラリにStringableが採用されたとする。
これでUTF8StringをIOライブラリで使えるようになるが、まだParsecでは使えない。
さらに将来のある時点で、Parsecが
>>971のようなクラスを採用したとする。
これでUTF8StringがIOでもParsecでも使えるようになる。
でも、このとき、Stringableを使って書かれたコードを変更する必要はない。
StringableクラスとListクラスは共存できる。
こういう風に、クラスは後付けでもなんとかなるのが特徴だと思う。
関数の動的バインディングのコストを言ってるんじゃないの?
HaskellというかGHC?で、この辺どうなのか全然知らないけど。
まあ、Stringableも型クラスなら変わらないから関係ないと思うけど。
誰か、
>>971を連中に提案してくれよ。
Stringable should be "List', othewise it shall bring about a civil war in Haskell applications.
みたいな。
でも、
>>971じゃ、[] 記法や : でのマッチが解決しないな。
これをStringableでも使えるようにしないとあかんな。
リストとして扱えないだけで嫌なんだけど
>
>>978 解説ありがとう。
>こういう風に、クラスは後付けでもなんとかなるのが特徴だと思う。
なるほど。急ぐ必要はないのか。
でも最初というか早い内からあった方が良いよね?共通クラス。
あと、リストの場合は型の問題(≒関数・演算子の問題)の他、
[]記法と : のマッチの問題があるんじゃない?
それもListクラス導入時に同時に解決すべき問題で急ぐ必要はないのかも知れないけど。
>>980 何を批判しているのか明確にしてくれ。
リストを使うのを妨げるような変更は一切話題になっていないと思うんだが。
>>982 >>981の
> []記法と : のマッチ
をStringableでも使いたいと言うことでは?
hoge (x:xs) = fuga x : hoge xs
をStringableでもやりたいって事かと。
実際、リスト処理はこれで書かれてると思うし。
ただ、[]は不要かな?新規にデータ構築する時だけだし、
文字列処理ではあんま使わないかも?リストが出来るだけで問題ないかも。
(:)と[]を変えるなら言語に手を入れなきゃならんからな。
>>971みたいなのを導入するならコードの書き換えが前提だと思ってたが。
屁理屈をこねだす初心者は
学習が全然進まない、という好例だな。
(:)と[]はリストのデータ構築子だからねぇ。
共通クラスに準拠させるんならhead,tail,foldrとかを使って書いてねって話しになると思う。
hoge [] = []
hoge (x:xs) = fuga x : hoge xs
は
hoge = foldr fuga empty
もしくは
hoge = map fuga
でOK
間違えた。
hoge = foldr (\x y -> cons (fuga x) y) empty
じゃないと型が合わない(^^;
hoge (x:xs) = fuga x : hoge xs
は、
データ構造の実装を直接触る、汚い・忌むべきコードなんだよ!
hoge xs = cons (fuga.head xs) $ hoge.tail xs
みたいにちゃんと関数で書くべきなんだ!!
もちろん、
bar Just a = foo a
bar Nothing = baz
もダメダメだ!!!
それじゃ結局分断は避けられないじゃん。
それとも、
>>989みたいな考え方を浸透させて、
hoge (x:xs) = fuga x : hoge xs
みたいのは非推奨にするの?言語として良い解なのかな、それ?
Haskellの特長であるパターンマッチングを捨てるのか。
MLに敗北するのか。
敗北厨かよ・・・
今のHaskellの仕様だとどんなに型クラスとかをいじくりまくってもUTF8Stringをx:xsにパターンマッチさせることは出来ない。
仕様自体を変更しないと無理。
あちゃー
もう文字列をリストで表現できるとか他言語に自慢できないのね