関数型プログラミング言語Haskell Part21at TECH
関数型プログラミング言語Haskell Part21 - 暇つぶし2ch2:デフォルトの名無しさん
13/01/21 02:17:12.49
関連書籍
・Introduction to Functional Programming Using Haskell (2nd ed.)
 URLリンク(www.amazon.co.jp)

・Haskell: The Craft of Functional Programming
 URLリンク(www.amazon.co.jp)

・The Fun of Programming
 URLリンク(www.amazon.co.jp)

・The Haskell School of Expression: Learning Functional Programming Through Multimedia
 URLリンク(www.amazon.co.jp)

・入門Haskell
 URLリンク(www.amazon.co.jp)

・ふつうのHaskellプログラミング
 URLリンク(item.rakuten.co.jp)

・Programming in Haskell
 URLリンク(www.amazon.co.jp)

・Real World Haskell
 URLリンク(www.amazon.co.jp)

・関数プログラミングの楽しみ
 URLリンク(www.amazon.co.jp)

・すごいHaskellたのしく学ぼう!
 URLリンク(www.amazon.co.jp)

3:デフォルトの名無しさん
13/01/21 02:18:09.04
関連リンク
・GHC Wiki
 URLリンク(hackage.haskell.org)

・A History of Haskell
 URLリンク(research.microsoft.com)

・関数型関連の用語集
 URLリンク(sky.zero.ad.jp)

・本物のプログラマはHaskellを使う
 URLリンク(itpro.nikkeibp.co.jp)

・Haskell API search Engine
 URLリンク(www.haskell.org)

 【簡単な使い方】
 1.検索バーに関数名を入れて検索
  例 map
 2.検索バーに型名を入れて検索
  例 (a -> b) -> [a] -> [b]

・Real World Haskell
 URLリンク(book.realworldhaskell.org)

・Learn You a Haskell for Great Good!
 URLリンク(learnyouahaskell.com)

4:デフォルトの名無しさん
13/01/21 02:24:30.26
Haskell初心者ですが、RealWorldHaskell読んでいて、状態モナドもどきを自作してみようと思って

newtype State s a = StateMonad { stateFunc :: s -> (a,s) }

とやってみて

somefunc :: (a -> b) -> State s a -> State s b
somefunc f (StateMonad g) = StateMonad( \s-> (f(fst(g s)), snd(g s)))

は通るのに

instance Functor (State s) where
fmap :: (a -> b) -> State s a -> State s b
fmap f (StateMonad g) = StateMonad( \s-> (f(fst(g s)), snd(g s)))

が通らないのがわからなくて困っています。

★質問: fmap をどのように宣言するのが正解なのでしょうか?
(fmap :: (a -> b) -> State s a -> State s b の一行を消しても型推論で通りますが、それは気持ち悪いのです)。

5:デフォルトの名無しさん
13/01/21 13:10:15.17
1(゚д゚ )乙 これは乙じゃなくてポニーテールなんたらかんたら

自分も基礎的質問で申し訳ないが
Free Monadがらみの記事にあった
data Fix f = Fix (f (Fix f))
はどういう意味になるんでしょう?
data Fix f = FixC (f (Fix f))でもいいものだと思いますが、コンストラクタ引数のf (Fix f)がわからんとです。FixCに2つの引数を渡す?
でもそれだとdata Fix f = FixC f (Fix f)となるんでしたでしょうか?
二つの型を型引数としてもつ型を渡すという意味?
URLリンク(www.haskellforall.com)

6:デフォルトの名無しさん
13/01/21 14:48:42.62
>>5
data Fix f =Fix (f (Fix f))
とすると、値コンストラクタFixは、ひとつの f (Fix f) 型の引数をとる

Fixはkindが (*->*)->*
fはkindが *ー>*
つまり、f自体が何かひとつの型引数をとるということ

fを[]とすれば
Fix::[Fix []] ー> Fix []

fをMaybeとすれば
Fix::Maybe (Fix Maybe) -> Fix Maybe

fを(,) a とすれば
Fix::(a, Fix ( (,) a ) ) -> Fix ( (,) a )

7:4
13/01/21 19:10:00.99
教わって解決しましたマン
Functorインスタンスはfmap の型宣言書いちゃいけないんですね

8:デフォルトの名無しさん
13/01/22 10:22:35.99
>>6
重ねてですまんが"f(Fix f)"の意味が分からんです・・・
Fix fの値を受け取るコンストラクタを持つfという型って意味でよい?

9:デフォルトの名無しさん
13/01/22 10:50:24.22
f (Fix f)は型引数としてFix fをとる型
[Fix f]とかMaybe (Fix f)とかIO (Fix f)

10:デフォルトの名無しさん
13/01/22 11:51:18.90
了解です。ありー
ちょっと咀嚼してきまふ(´・ω・`)

11:デフォルトの名無しさん
13/01/23 14:56:26.88
新スレおめでとうございます^^

12:デフォルトの名無しさん
13/01/23 23:19:59.21
>>4
標準だと、instance宣言の中ではメソッドの型は宣言できない
書くまでもなく型は決まってるし

13:デフォルトの名無しさん
13/01/24 05:02:59.40
エラーメッセージでそのこと言及してくれよコンパイラ

14:デフォルトの名無しさん
13/01/24 23:44:07.74
>>12
ありがとうございます。

15:デフォルトの名無しさん
13/01/25 16:21:32.33
haskellで書いたプラグインを動的に読み込む仕組みってないですか?

16:デフォルトの名無しさん
13/01/25 17:17:33.46
xmonad方式はどう?

17:デフォルトの名無しさん
13/01/26 01:40:13.71
>>16
言語処理系を作ってるので、ユーザー側で他の処理系(ghc)が必要っていうのは避けたいんですよね
ファイルをディレクトリに置いたら読み込めるっていうのが理想なんですが
やっぱりffiで共有ライブラリを読み込むしかないんですかね

18:デフォルトの名無しさん
13/01/28 14:21:16.47
function sum(a, b){
return a + b;
}

sum("こんにちは");

これをhaskellで書くとどうかけますか?

19:デフォルトの名無しさん
13/01/28 15:07:14.40
わけがわからないよ

20:デフォルトの名無しさん
13/01/28 17:43:39.13
>>18

sum' x y = x + y

main = let
hello = sum' "こんにちは"
in putStrLn "Hello"

コンパイルエラーになるけど

21:デフォルトの名無しさん
13/01/28 17:46:56.34
>>20
オブジェクト指向しかやってないからさっぱりわからないです
関数型ってむずかしいですね

22:デフォルトの名無しさん
13/01/28 18:10:06.26
わけがわからないよ…

23:デフォルトの名無しさん
13/01/28 18:10:14.38
>>18は何言語でどういう動作を期待してるの?

24:デフォルトの名無しさん
13/01/28 18:13:36.33
>>21
自分も勉強中なのだけど、「入門Haskell」や
「すごいHaskellたのしく学ぼう!」 (>>2を参照)
あたりを通読するのを勧める。C++知ってる人がPerlを学ぶとか
Pythonを学ぶのとかなり違った難しさがある。

英語がさほど苦手ではないなら「すごいHaskellたのしく学ぼう!」
の原書は
URLリンク(learnyouahaskell.com)
で読めるよ。

25:デフォルトの名無しさん
13/01/28 18:14:06.91
サム「こんにちは」

26:デフォルトの名無しさん
13/01/28 18:48:19.34
プログラミングhaskell読んでるけど7章あたりで頭が追いつかなくなってきたわ。。。

27:デフォルトの名無しさん
13/01/28 19:11:36.20
dataのあたりで今詰まってる。ShapeとかCircleで説明してるやつ。
オブジェクト指向とちょうど逆になってるのかな。
何が逆かはうまく説明できないけど、なんかそんな感覚。

28:デフォルトの名無しさん
13/01/28 20:00:44.19
オブジェクト指向って何やってんの
そうまで他の言語を難しく考えることもないと思うんだけど

29:デフォルトの名無しさん
13/01/28 20:46:02.21
オブジェクト指向的にインタフェースと多態で書くと、
・データの種類(クラス)の追加は簡単
・処理(メソッド)の追加は面倒
代数的データ型で書くと、
・データの種類(構築子)の追加は面倒
・処理(パターンマッチする関数)の追加は簡単

30:デフォルトの名無しさん
13/01/28 21:20:37.19
データの種類で最も重要なのは
・null
・null以外
の二種類
nullという種類の追加が面倒という性質は
静的型付けの存在理由に関わる重要な性質だ

31:デフォルトの名無しさん
13/01/28 23:18:48.92
オブジェクト指向的な多態とnullは関係ないだろ
Haskellにだって、nullよりある意味厄介な⊥というのがあるし

32:デフォルトの名無しさん
13/01/29 00:08:17.73
lazyは厄介だ
実行時よりもコンパイル時という考え方に反する

33:デフォルトの名無しさん
13/01/29 00:12:58.10
bottomを厄介者扱いとかバチあたりな

34:デフォルトの名無しさん
13/01/30 17:17:32.64
リストをたくさん結合すると非効率というのがいまいちわからない
実際どういう状況で非効率になるの?

35:デフォルトの名無しさん
13/01/30 17:43:29.80
たくさんが問題じゃなくて ++ が問題。
後半のリストは共有できるにしても、前半のリストは複製しなきゃなんない。

36:デフォルトの名無しさん
13/01/30 23:43:24.50
>>29
オブジェクト脳の俺にもう少し(もうだいぶ)詳しく教えてくれないか ?

ちなみに上の人とは別でこのすれ初かきこです

37:デフォルトの名無しさん
13/01/31 00:16:55.85
>>34
配列ならスペースを多めに取ってnullを入れておく状況とか

仕様を正確に知っている人でも、必要なスペースは予測できない
仕様書には知っていることだけ書けばいいが
コードには予測できないことまで書かないと上手く動かない

38:デフォルトの名無しさん
13/01/31 01:27:57.49
関係ないが、講議で、ソフトウェア科学における最悪の発明が「NULL」という話を聞いた

39:デフォルトの名無しさん
13/01/31 12:12:36.80
発明した人と批判した人の両方が賞をもらえるという話をどこかで聞いたような気がする

40:デフォルトの名無しさん
13/01/31 17:04:09.49
>>38
UNKNOWN先生がアップを始めたようです

41:デフォルトの名無しさん
13/01/31 19:36:37.05
最高の発明だよ

42:デフォルトの名無しさん
13/02/01 02:09:57.58
NULLはビリオンダラーミステイク by Tony Hoare

43:デフォルトの名無しさん
13/02/01 08:45:26.97
言語を選んだ時点で失敗が確定するというのは
時期尚早な最適化の話と内容が180度違うから困る

44:デフォルトの名無しさん
13/02/01 19:43:14.96
'こんにちはundefined'
許すまじundefined

45:デフォルトの名無しさん
13/02/02 12:14:09.96
⊥が現れるのは再帰がある場所に限定される
が評価されるタイミングは限定されない

46:デフォルトの名無しさん
13/02/06 21:22:00.54
いちおうMaybeモナドすげEEEEEEってのはわかったつもりなんだけどさ

モナド使うとなんでIOの副作用が分離されるの ?
IOってところに環境のいろんなところが入っているから
それをひきずり回しているからIOじゃないところは純粋であるって説明
どっかで読んだんだけど、具体的にはどうやってるの ?

おしえてキボンヌ

47:デフォルトの名無しさん
13/02/06 21:34:07.28
指定したN番目の値を返す関数を作りたいのですが、上手く出来ません。
例えば、nthElementIs [1,2,3,4] 3 > 3見たいにしたいです。

isTrue :: Int -> Bool
isTrue number
| number > 0= False
| otherwise= True

nthElementIs :: [a] -> Int -> a
nthElementIs list number = case (list) of
[] -> case (number) of
0 -> []
otherwise -> error"okh"
(x:[]) -> case (number) of
1 -> x
otherwise -> error"z"
(x:xs) -> case (number) of
isTrue -> error"df"
otherwise -> nthElementIs xs (number - 1)

48:デフォルトの名無しさん
13/02/06 21:36:19.56
>>46
どうやってという疑問は比較的簡単で
Stateモナドで状態を引きずり回しているのと同じように
RealWorldを引きずり回しているのが IO

49:デフォルトの名無しさん
13/02/06 21:39:03.05
無限リストなの?

50:デフォルトの名無しさん
13/02/06 22:10:30.55
>>47
よーしパパそれほどHaskellerじゃないけど調子に乗って習作書いちゃうぞー

nthElementIs :: [a] -> Int -> a
nthElementIs (x:xs) num | num == 1 = x
. | num > 1 = nthElementIs xs (num - 1)

これじゃいかんの ?

不適なデータが来ても何とかするなら

nthElementIs :: [a] -> Int -> Maybe a

nthElementIs [] _ = Nothing
nthElementIs (x:xs) num | num < 1 = Nothing
. | num == 1 = Just x
. | num > 1 = nthElementIs xs (num - 1)

とか

51:デフォルトの名無しさん
13/02/06 22:20:12.67
>>50
ありがとうございます。
コードがすっきり分かり易いです。
エラー書くよりはMaybe使った方がやはりいいのでしょうか?
後、ガードとcaseの使い分けはあるのでしょうか?
聞いてばっかですいません。

52:デフォルトの名無しさん
13/02/06 22:23:54.11
>>50はものすごく教科書的でいいね。

nthElementIs xs num = last . take num $ xs

俺ならこの質問されたらめんどくさいから一行でこう書くわ
駄目な大人になってしまった

53:デフォルトの名無しさん
13/02/06 22:37:16.96
nthElementIs xs n = xs!!(n-1)

54:デフォルトの名無しさん
13/02/06 22:41:13.31
>>53でFA
これ以外の正解はない

55:デフォルトの名無しさん
13/02/06 22:46:36.68
明らかに学習目的なのに既存の関数を使って正解って…

あとインデックスは0から開始するように習慣づけるべきだと誰も指摘しないことに驚いた

56:デフォルトの名無しさん
13/02/06 22:52:17.68
>>46
分離したというけど、無関係ではないよね
IOの中では関数を適用できるが、関数の中ではIOを実行できない、という関係
コールバック関数を自分でコールできないみたいな状況に似ている

57:デフォルトの名無しさん
13/02/06 22:56:07.24
既存の関数使わないでどう答えろと
(==)も(<)も(>)も(!!)も、全部既存の関数だぞ

58:デフォルトの名無しさん
13/02/06 23:20:28.47
monadだから分離されているというべきなのか。
IOの型修飾を外すには、(>>=)するしか無いから分離されているというか、、、

59:50
13/02/06 23:51:46.77
>>51
> エラー書くよりはMaybe使った方がやはりいいのでしょうか?
> 後、ガードとcaseの使い分けはあるのでしょうか?

すまん。自分も習いはじめでよくわからんとです。

>>52
教科書読んだばかりですから !!
一流のHaskellerになると関数合成ばしばし使うのですね。
自分、関数合成にまだ発想が行きません。

便乗質問ですが、ピリオドとダラーの使い分けなんですけど、
nthElementIs xs num = last . take num $ xs

nthElementIs xs num = last $ take num $ xs

nthElementIs xs num = last $ take num xs
も結果は同じなのですがどう使い分けてます ?

本来なら(引数の順番さ000え逆だったら、nthElementIs num xsだったら)
nthElementIs num = last . take num
って書きたかったのでしょうけど


>>55
> あとインデックスは0から開始するように習慣づけるべきだと誰も指摘しないことに驚いた

そうしなければいけない何らかの事情があるのかと思ってた
((!!)を使うといけないのもエラー処理のためとか今後の拡張とかの理由かと思ってた)

60:デフォルトの名無しさん
13/02/06 23:55:00.06
>>57
「既存の(ほぼ答えそのものの)関数を使って…」って書いたら満足だったか?

ていうか、よく見たら思った以上に酷い回答ばっかだった

まず、「is」が付く名前は慣習的にBoolを返すものだから、「nthElement」か単に「nth」とすべき。

>>52はありえない
>>50
(nthElement [] n) がNothingを返すのはいいが、
(nthElement [1,2,3,4] -1) などは明らかにプログラミングエラーなのだからエラーにするべき。
(他の言語なら最後の要素を返すのも考えられるが)
そうしないと潜在的なバグがコードに紛れ込み、かえって品質を落とすことになる。

入門書の最初の方に出てくるような例なんだから、これくらいまともに回答してくれよ

61:デフォルトの名無しさん
13/02/07 00:37:35.34
人に文句言ってばかりで自分では何もしないカスがいるみたいだから、
俺が代わりにPreludeに載ってる!!の例から丸写ししてやる。

nthElement :: [a] -> Int -> a
nthElement xs n | n < 1 = error "nthElement: negative index"
nthElement [] _ = error "nthElement: index too large"
nthElement (x:_) 1 = x
nthElement (_:xs) n = nthElement xs (n - 1)

62:デフォルトの名無しさん
13/02/07 00:52:21.07
丸写しして気づいたけど、2chでの回答としては>>53が一番の正解で間違いないね
ほぼ答えそのものの関数があるならそれを示せばいいだけだ。わざわざ転記する必要ねーじゃん

63:デフォルトの名無しさん
13/02/07 01:08:02.48
>>61
酷いと言われて悔しかったのはわかるが、実際にいちばんまともなコメントをしているのは自分だと思うぞ。
名前から「Is」を削ったのは納得したからじゃないの?
(インデックスをわざわざ1から開始にするのは意味がわからないが…)

>>62
それなら答えは(!!)を使えということだろ。
あるいはソースへのリンクを貼るか
URLリンク(www.haskell.org)

64:デフォルトの名無しさん
13/02/07 01:17:45.78
病院池

65:デフォルトの名無しさん
13/02/07 01:27:36.33
>実際にいちばんまともなコメントをしているのは自分だと思う
実際に一番まともなコメントは>>63以外にないと思うぞ。マジで。
名前は突っ込まれたから変えたけど正直問題の本質と関係ないからどうでもいいし

>インデックスをわざわざ1から開始にするのは意味がわからない
問題読み直したら?

>それなら答えは(!!)を使えということだろ。
だからそれが>>63で既出だって話。ぐだぐだ書いてる俺らより余程簡潔にまとめてるし、
ソースのリンクなんか貼らなくてもPreludeのソースなんてド素人でも見つけられる。

66:デフォルトの名無しさん
13/02/07 01:28:48.39
安価ミス。>>63じゃなくて>>53

×実際に一番まともなコメントは>>63以外にないと思うぞ。
○実際に一番まともなコメントは>>53以外にないと思うぞ。

×だからそれが>>63で既出だって話。ぐだぐだ書いてる俺らより余程簡潔にまとめてるし、
○だからそれが>>53で既出だって話。ぐだぐだ書いてる俺らより余程簡潔にまとめてるし、

67:デフォルトの名無しさん
13/02/07 01:31:57.55
>>62
あなたがそれを一番の正解と判断するに至った価値基準は?
それはあなた以外の人も持っていて当然のもの?
それ以外の価値基準が存在しうることは理解してる?

68:デフォルトの名無しさん
13/02/07 06:04:09.76
なんかここ怖い

69:デフォルトの名無しさん
13/02/07 07:11:57.30
基地外隔離スレだから仕方ない

70:デフォルトの名無しさん
13/02/07 07:26:24.38
>>65,66
なんでそんなに切れてるわけ?
>>47を見れば初学者なのは一目瞭然なんだから、インデックスは0から始めるものだと教えてやるのは当然だし、
どう考えても争うような本質的な問題じゃないだろ?

> ソースのリンクなんか貼らなくてもPreludeのソースなんてド素人でも見つけられる。
リンクを貼るの難しそうだしね。無理言って悪かったよ。

71:デフォルトの名無しさん
13/02/07 07:26:39.08
Haskell怖いです(震え声)

72:デフォルトの名無しさん
13/02/07 07:30:47.90
Haskellは怖くないよ
>>47とかたぶんFizzBuzz並に簡単な問題
それさえもできない人が何故か回答してるからおかしくなってるだけで

73:デフォルトの名無しさん
13/02/07 07:55:12.22
nth elementの取り出しなんて、preludeのソース詠めばいいだろ

74:デフォルトの名無しさん
13/02/07 08:30:01.16
どうみても頭がおかしいのは>>60ひとり

75:デフォルトの名無しさん
13/02/07 10:25:36.22
入門書読んだ後は、!!とか自作して遊んでたな。。。(遠い目)

76:デフォルトの名無しさん
13/02/07 18:35:12.00
プログラミングhaskell
8章まで来たけど、いよいよ全く意味がわからなくなって挫折しそうボスケテ!

77:デフォルトの名無しさん
13/02/07 19:13:34.93
8章は載ってるコードじゃ動かないし、その後の章の知識が必要だから初見で理解するのはたぶん無理だろう
理解できると一番面白い章だけど、最初は適当に読み流した方がいい

78:デフォルトの名無しさん
13/02/07 20:39:42.42
8章から難易度がスコーンと上がるからな
すごいHの方に浮気するのもアリだと思う

79:デフォルトの名無しさん
13/02/07 21:16:21.92
個人的にはすごいHaskellの方が難しいと思う
とくに序盤は

80:デフォルトの名無しさん
13/02/08 01:55:53.33
RWHで挫折してまたRWHに戻ってくるまでが勉強です

81:デフォルトの名無しさん
13/02/08 13:22:59.19
dammy

82:デフォルトの名無しさん
13/02/09 12:25:40.88
>>77
8章はPreludeのdo,returnとかが邪魔してコード通り動かないよなw
とりあえずdo表記を使わず、Preludeにある関数は名前を変えて
なんとか練習問題まで終わらせたけど・・・。

9章の電卓も期待した動きと違う。主に遅延評価のせいだと思うけど。
入力した式が評価されるまでputStrの実行も遅延させられるみたいで、
電卓のテンキー(飾り)が表示されない・・・。

俺は練習問題に関してはここで心が折れたw

本文は、10章まで読んだけど、11章からは応用問題みたいだから
後でいいやと読むのを止めたw

83:デフォルトの名無しさん
13/02/09 18:22:47.83
Haskellの最初の挫折ポイントはモナド
次の挫折ポイントが値の直接変更はSTモナド内で引きこもってやるということ

次の挫折ポイントがモナド変換

84:デフォルトの名無しさん
13/02/09 19:15:19.99
モナドって、"最初の"挫折ポイントか?
私は、まだモナド山に入山してさえいない。その前でちょっと挫折気味。

今、プログラミングHaskell 13章を読んでいる最中。

すごいHaskellはアダプティブファンクターのところで止まっている。

プログラミングHaskell を読み終わったら、すごいHaskellのアダプティブファンクター
~モナドのところに進んでみる。

85:デフォルトの名無しさん
13/02/09 19:19:40.65
adaptive functor!

86:デフォルトの名無しさん
13/02/09 20:58:26.45
>アダプティブファンクター
挫折した感がものすごく良く伝わってくる

87:デフォルトの名無しさん
13/02/09 21:32:25.92
挫折ポイントはいっぱいある。
型クラス、型構築子、データ構築子などの独特な型の世界が
行く手を阻んでいる。
ついでに型でエラーが出まくって慣れないと
何のエラーかよくわからんのがなぁ。


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch