トップページtech
1001コメント285KB

関数型プログラミング言語Haskell Part22

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2013/03/23(土) 12:34:19.09
haskell.org
ttp://www.haskell.org/

日本語サイト
ttp://www.sampou.org/cgi-bin/haskell.cgi
ttp://www.shido.info/hs/

過去ログ
関数型プログラミング言語Haskell
Part1 ttp://pc.2ch.net/tech/kako/996/996131288.html
Part2 ttp://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 ttp://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 ttp://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 ttp://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 ttp://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 ttp://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 ttp://pc11.2ch.net/test/read.cgi/tech/1193743693/
Part9 ttp://pc11.2ch.net/test/read.cgi/tech/1211010089/
Part10 ttp://pc12.2ch.net/test/read.cgi/tech/1231861873/
Part11 ttp://pc12.2ch.net/test/read.cgi/tech/1252382593/
Part12 ttp://hibari.2ch.net/test/read.cgi/tech/1272536128/
Part13 ttp://hibari.2ch.net/test/read.cgi/tech/1286706874/
Part14 ttp://hibari.2ch.net/test/read.cgi/tech/1299385928/
Part15 ttp://hibari.2ch.net/test/read.cgi/tech/1310199414/
Part16 ttp://toro.2ch.net/test/read.cgi/tech/1317958045/
Part17 ttp://toro.2ch.net/test/read.cgi/tech/1325510368/
Part18 ttp://toro.2ch.net/test/read.cgi/tech/1331902463/
Part19 ttp://toro.2ch.net/test/read.cgi/tech/1340760070/
Part20 ttp://toro.2ch.net/test/read.cgi/tech/1350428908/
Part21 ttp://toro.2ch.net/test/read.cgi/tech/1358702176/
0552デフォルトの名無しさん2013/06/10(月) 11:47:26.95
Data.Function.on

(++) `on` show
compare `on` snd
0553デフォルトの名無しさん2013/06/10(月) 11:59:19.81
(*ゝω・)ノ アリガd♪
05545482013/06/10(月) 13:12:14.00
>>549
言葉が悪かったな、本当に済まなかった。
言いたかったことはこれ
初心者はPrelude禁止とか変な縛りはせず、
Preludeの中の関数の定義を読むか、
自分から書きなおした方がいいんじゃないか、勉強的に

関数型プログラミングをするのは、難しい問題を分解して
多くの簡単で小さな問題を解く関数を書くことではないか。
だからmapを使え。mapがなにしてるかわからないのなら
書きなおして身につける方がいい

僕は上の母語の日本語じゃない奴なので
変な文&正しくないマナーは許してくれ(汗
0555デフォルトの名無しさん2013/06/10(月) 19:08:11.83ID:lZ0F4JgH!
>> 547, 548
ありがとうございます。
出きるだけprelude関数を使いたくなかった理由はjavaやってる時に、
ずっとライブラリーを貼って付けるみたいな作業を感じたので。
それにしても、Haskell意外と面白いな。これからもっと勉強します。
0556デフォルトの名無しさん2013/06/10(月) 20:17:18.37
Javaは全然知らんが、mapやfoldは
関数型の基本だから覚えるべし。
0557デフォルトの名無しさん2013/06/10(月) 20:32:08.37ID:lZ0F4JgH!
>>556
foldlって無限のリストでも使用できるんですよね。
ま〜take, drop, map, zip, filter位は何とか覚えるようにしてます。
Haskell覚えること多いな。
algbraic type は自分でdata使って独自の型を作れるのは分かったノですが,abstract data typeが理解できない。
既存のIntやBool型などブラックボックス化されてるのがそうなのですか?
0558デフォルトの名無しさん2013/06/10(月) 21:43:32.16
>>554
purelude は弾けても fuga は死にそうです‥‥
0559デフォルトの名無しさん2013/06/10(月) 23:18:41.40
>>557
本一冊読破すればそのような基本的な疑問はすべて解消すると思う
(まあ抽象データ型は関数型に限った話じゃないと思うが)
Prelude関数を自分で書いてみるのはHaskellの基本的なテクニックを学べる点では良い
ただプログラム書くのにいちいち定義してたら面倒だからライブラリがあるんでないのかね
これはどんな言語でも同じだと思うけど。さらにいえばファイル入出力とかのコードはどの言語でも
似たようなつまらないコードを書かざるをえない。こういう作業感はやることに依存すると思う。
0560デフォルトの名無しさん2013/06/11(火) 04:43:03.72
君達に許された時間は有限なんだ
車輪の再発明にかまけてる時間があるのか
0561デフォルトの名無しさん2013/06/11(火) 06:06:00.66
>>559
「ふつうの・・・」では無理ね。
0562デフォルトの名無しさん2013/06/11(火) 06:45:03.82
>>560
再発明しかお金がもらえないんです
0563デフォルトの名無しさん2013/06/11(火) 11:15:06.31
習作から入る事前提のプログラミング教育も問題だけどな。
0564デフォルトの名無しさん2013/06/11(火) 23:08:35.87
>>542
pairUp [1,3,5]
はどういう結果になるのが正しいと思ってる?
0565デフォルトの名無しさん2013/06/11(火) 23:26:39.31
>>557
抽象データ型は代数とみなせるから代数データ型とも言う事があるというだけで2つは同じもの。

構造化プログラミングはプログラムの連続分解というものを導入する事で大規模ソフトウェアの
開発を可能にしたけれど、データ構造の変更とデータ構造を操作する手続きの変更に弱かった。
抽象データ型を導入することでその欠点を補いつつ構造化プログラミングが可能になった。
(プログラムの連続分解をするにあたって有害だったのがgoto文)

Haskellでは例えば昔話題になったオードリー・タンのperl6は構造化プログラミングを実践してた。
ただ、抽象データ型はあんまつかってなかったと思う。
0566デフォルトの名無しさん2013/06/11(火) 23:33:20.87
いやー構成要素の並びが外部に影響する代数データ型を抽象データ型とはとても言えない
0567デフォルトの名無しさん2013/06/11(火) 23:41:09.19
せやね
0568デフォルトの名無しさん2013/06/11(火) 23:48:13.30
並びについては知らないな。ゴーゲン以降出てきたのか?そんな話。
0569デフォルトの名無しさん2013/06/11(火) 23:55:19.69
あとついでに、今思えば、オードリー・タンのpugsはHaskellだからというよりも
Haskellで構造化プログラミングをやったから大規模開発ができたというのが正しいと思う。
0570デフォルトの名無しさん2013/06/12(水) 13:54:46.68
僕は数学オリンピックで上位ですがC言語しか使ってません
知り合いの人は中学数学すらおぼつかないバカなのにHaskell使ってることを自慢してきます
どうすればいいでしょうか?
0571デフォルトの名無しさん2013/06/12(水) 14:04:35.02
算数はすごいけど数学はすごくない
0572デフォルトの名無しさん2013/06/12(水) 17:56:37.86
>>570
くだらないことを質問するな
0573デフォルトの名無しさん2013/06/12(水) 20:58:46.80
Haskell使ってみたいけど作りたいものがない
0574デフォルトの名無しさん2013/06/12(水) 21:12:07.51
だから何だ?
0575デフォルトの名無しさん2013/06/13(木) 00:20:21.19
カレーでも作ってろ
0576デフォルトの名無しさん2013/06/13(木) 04:39:36.23
>>573
ナンプレパズルを解くプログラム
0577デフォルトの名無しさん2013/06/13(木) 10:51:56.41
>>557
> ま〜take, drop, map, zip, filter位は何とか覚えるようにしてます。
> Haskell覚えること多いな。

いや、その辺は現代的なLispの影響を受けた言語の基本かと。
0578デフォルトの名無しさん2013/06/13(木) 21:36:42.93
>>573
解説サイト作れ
0579デフォルトの名無しさん2013/06/14(金) 12:33:39.45
確かに入門向けの解説がないから、初心者向けのが、作者の理解と共に読めるサイトがあったらいいな。
0580デフォルトの名無しさん2013/06/14(金) 13:38:17.60
>>575
おれは評価する
0581デフォルトの名無しさん2013/06/14(金) 16:28:04.48
haskellでeval男の人って…
0582デフォルトの名無しさん2013/06/14(金) 16:30:11.48
>>580
お前575だろ
0583デフォルトの名無しさん2013/06/15(土) 00:08:38.79
>>575
俺も評価する
0584デフォルトの名無しさん2013/06/15(土) 00:18:06.54
俺は遅延評価する
0585デフォルトの名無しさん2013/06/15(土) 00:28:12.51
あぶねえ
こんな微妙なネタで被るところだった
0586デフォルトの名無しさん2013/06/16(日) 03:18:07.64
Haskellを使うために必要な知識を得たくて勉強してるのに、「モナド」という単語のせいで、Haskellプログラムを表現するためだけに必要な本来の目的とは関係ない特殊な知識へ労力がミスリードされてる気がする
0587デフォルトの名無しさん2013/06/16(日) 08:26:58.96ID:F2SjiwBC!
ttp://www.haskell.org/haskellwiki/OpenGLTutorial1
の下の方に、四色で彩られた四角形の描写があります。
color $ (Color3 (1.0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) 0 0)のColor3やVertex3はメソッドだと分かったノですが、
parse error on input `color' とでました。
何がいけないのでしょうか?

import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT

main :: IO ()
main = do
(progname, _) <- getArgsAndInitialize
createWindow "Display a screen"
displayCallback $= display
mainLoop
display :: IO ()
display = do
clear [ColorBuffer]
renderPrimitive Quads $ do
color $ (Color3 (1.0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) 0.2 0)
vertex $ (Vertex3 (0.2::GLfloat) 0.2 0)
vertex $ (Vertex3 (0.2::GLfloat) 0 0)
color $ (Color3 (0::GLfloat) 1 0)
vertex $ (Vertex3 (0::GLfloat) 0 0)
vertex $ (Vertex3 (0::GLfloat) (-0.2) 0)
~~~
flush
0588デフォルトの名無しさん2013/06/16(日) 09:07:18.73
>>587
コピペしてimportとmainを追加したらコンパイル通ったよ
(実行したらウィンドウシステムが落ちたけどたぶん俺の環境の問題)
コピペミスじゃないか?
0589デフォルトの名無しさん2013/06/16(日) 16:07:27.56ID:F2SjiwBC!
>>588
多分何処かにミスがあったのだと思います。コンパイーラーは通ったのですが、どうやってmainを呼べばいいんでしょうか?
今まではghciからmainを呼んでいたのですが。
Haskell ? ghc -package GLUT game.hs -o game. ?
[1 of 1] Compiling Main ( game.hs, game.o )
Linking game. ...
Haskell ? main
zsh: correct main to man [nyae]? n
zsh: command not found: main
0590デフォルトの名無しさん2013/06/16(日) 17:10:28.04
./game
0591デフォルトの名無しさん2013/06/16(日) 21:09:33.37
>>584
言い得て妙だな
(必要になるまで575の評価をしない)
0592デフォルトの名無しさん2013/06/16(日) 21:24:19.88ID:F2SjiwBC!
>>590
おお、ありがとうございます。
0593デフォルトの名無しさん2013/06/17(月) 04:44:22.94
>>586
叙述トリックだ
0594デフォルトの名無しさん2013/06/17(月) 08:47:10.52
モナドモナドしたいからhaskell勉強するんだよ
0595デフォルトの名無しさん2013/06/17(月) 11:14:29.81
最小完全定義の説明ってちょっと分かりづらくないですかね
具体的には、Eqのインスタンスを宣言するときに(==), (/=)のどちらかを実装するって話(すごH本、wikibooksで確認)
いきなりEqクラスのデフォルト実装が循環定義になってるのを見せられると一瞬面食らう
学習上であまり直感的じゃない部分だと思うんだけど
ググってもあまり悲鳴が上がってないのが不思議
(ブログを見ると「らしい」という曖昧に理解してる感がある文章に出会える)
0596デフォルトの名無しさん2013/06/17(月) 11:48:08.06
>モナドモナドしたいからhaskell勉強するんだよ
上からのフェロモンで動いてる昆虫そのもの
0597デフォルトの名無しさん2013/06/17(月) 15:57:31.37
>>595
(==)だけ実装してる場合
x /= y を簡約化すると
not (x == y) -- x /= y の定義
not False -- (==は実装済みなので) x == y = False だとして
True -- not の定義
というふうになる
(/=)だけ実装してる場合も同様
普通(デフォルト)は==の否定(not)は/=と定義されるよね(逆もまた然り)という
実装が与えられてるだけで、そんなの関係ねえと思う人は(==)も(/=)も定義すればよい
data Human = Human { age :: Int, sex :: Int }
instance Eq Human where
x == y = sex x == sex y -- 左辺と右辺の(==)は違う
x /= y = age x /= age y
Q. John(19)はMary(19)は同じ(==)人物か
A. いいえ
Q. じゃあ二人は違う(/=)人なのね
A. いいえ
Q. ぐぬぬ
ってなるけど(最小完全定義の説明にはなってないかな
0598デフォルトの名無しさん2013/06/17(月) 16:13:40.07
循環定義になってるから、どっちかをオーバーライドして使ってね、という
意図ということでいいと思うけどな。

で、排中律が成立しているか、みたいなチェックの枠組は言語にはないよ、と。
0599デフォルトの名無しさん2013/06/17(月) 16:13:52.83
いや595はもう理解してるんでしょ
最初見たときは戸惑った
これじゃあ無限に巡回するじゃないか、と
ただそこで深く悩むことはなく
そのあとに出てきた信号をインスタンスにする例で
すぐに理解できた
0600デフォルトの名無しさん2013/06/17(月) 21:25:09.17
>>586
ミスリードで思い出したけど
このリードって導くの意味のリードだったってつい最近まで知らんかったの思い出した
読むの方だと思ってたwwwwwww
0601デフォルトの名無しさん2013/06/17(月) 23:04:10.61
今、英和辞典で misslead を探してどこにも無いと焦ったバカが日本に数万人は居るな
0602デフォルトの名無しさん2013/06/18(火) 00:10:00.88
Haskellプログラマが数万人も居るなら日本は安泰だな。
0603デフォルトの名無しさん2013/06/18(火) 00:58:21.30
モナドが云々は、純粋関数型のIOを歴史的にみるといいんでないかい。
http://www2.gssm.otsuka.tsukuba.ac.jp/staff/kuno/lectures/12/2012-04-TopicsPL6.pdf
といっても、そうなると焦点がそこに絞られちゃうからこんな感じでよいのでは?
http://www.sampou.org/haskell/tutorial-j/io.html
0604デフォルトの名無しさん2013/06/19(水) 00:25:45.13
IOモナドはC言語の世界でいうとyaccに近い
という理解でよろしいでしょうか?
0605デフォルトの名無しさん2013/06/19(水) 06:29:26.34
ヤックル!ヤックル!
0606デフォルトの名無しさん2013/06/19(水) 07:13:57.60
>>604
なぜ?
0607デフォルトの名無しさん2013/06/19(水) 09:12:46.56
なんでpipeとかもっと適切なのを思わないんだろ
0608デフォルトの名無しさん2013/06/19(水) 09:18:26.09
>>602
本当にそうなら、作ればいいだけではないか。
0609デフォルトの名無しさん2013/06/20(木) 22:59:37.42
質問です

これがOKで
Prelude> product [x | x <- [1..10000] , mod x 10 /= 0 , mod x 10 /= 2 , mod x 10 /= 5]

これがNGなのは何故ですか?
Prelude> product [x | x <- [1..10000] , not $ (mod x 10) <- [0,2,5] ]
<interactive>:15:36: Parse error in pattern: mod
0610デフォルトの名無しさん2013/06/20(木) 23:22:08.48
>>609

[x | x <- [1..1000] , y <- [0,2,5], not $ (mod x 10 == y) ]
0611デフォルトの名無しさん2013/06/20(木) 23:33:50.07
product $ filter (\x -> (and (map (\y -> (not $ mod x 10 == y)) [0,2,5]))) [1..100]
0612デフォルトの名無しさん2013/06/20(木) 23:38:31.57
>>609
・mod の構文が間違っている
・(mod ...) が Int 型とマッチングしない
・[x| x <- ...., y <- ....] は (x,y) の全組み合わせを生成して、重複を削除せずにxだけ並べる
0613デフォルトの名無しさん2013/06/21(金) 00:09:06.83
ん?GHCiだと通ったけど
Prelude> product [x | x <- [1..10000], mod x 10 /= 0, mod x 10 /= 2, mod x 10 /= 5]
06146092013/06/21(金) 00:58:46.81
>>613
代名詞が分かり辛かったですが、"これ"は上を指しています

>>612
:t mod で確かめましたが、mod での行き先(?)は Int とは限らないのですか…
では、
Prelude> :i Integral で
instance Integral Integer
instance Integral Int
とあるのにも関わらず、(mod ...) が [0,2,5] :: [Int]
の要素である Int 型として推論されないのはなぜですか?

ググる際のキーワードも教えていただけると有難いです
0615デフォルトの名無しさん2013/06/21(金) 01:01:11.01
>>614 下を指しています
0616デフォルトの名無しさん2013/06/21(金) 02:01:36.60
>>614
リスト内包表記 [ x | x <- hoge ] の正体は hoge >>= \x -> [x]
だから<-の左辺でパターンマッチ例えば(x:xs)とか(x,y)を使える
だけど普通の関数と同様に(mod x 10)というパターンマッチは使えない
0617デフォルトの名無しさん2013/06/23(日) 18:36:49.35
説明がかみ合ってないので
モナド難しい!と思われた初心者をまた逃したな
0618デフォルトの名無しさん2013/06/23(日) 19:34:36.60
fact n = fact-tail n 1
    where fact-tail 1 acc = 1
        fact-tail n acc = fact-tail (n - 1) (acc * n)

みたいに素直に再帰で書き下せるところをいちいち末尾再帰に書き換えるように
なってしまいました。

こういうのってプログラム見にくいんじゃないかなぁと思いますが、
どうでしょうか?

好きにしろって言われるかもしれませんが
0619デフォルトの名無しさん2013/06/23(日) 19:39:39.27
>>618
見にくくなるかなぁと思いながら、それでもわざわざ末尾再帰にするくらいだから、
パフォーマンスの向上を狙っているのだと思う。

それが、「どれほどの」向上に繋がっているのか正しく理解しているのなら、
それでいいんでないか?
トレードオフでパフォーマンス側をとったというだけのことだから。

どれほどの向上なんだろ? という状態だったら、直ちに調査してみることを勧める。
0620デフォルトの名無しさん2013/06/23(日) 20:13:36.12
がんばれ〜
0621デフォルトの名無しさん2013/06/23(日) 20:32:23.73
おれは逆に、何でも末尾再帰で書いてたのが、Haskell 勉強してからはfold系が使えないか考えるようになったなぁ。
0622デフォルトの名無しさん2013/06/24(月) 02:23:24.02
何でもかんでも末尾再帰で書く理由は自動プログラミング
出力されるコードが末尾再帰になるようにプログラムを帰納するテクニックがある

別の言い方をすると、出力の一覧を見てコードを書くときに、頭を使わずに同じ手順でコードを書くときは、末尾再帰の方が楽な場合がある
(手は猛烈に動かすが、頭は使わないという意味で)
0623デフォルトの名無しさん2013/06/24(月) 12:41:37.00
お、おう
0624デフォルトの名無しさん2013/06/24(月) 15:01:35.61
狐憑き Haskell kita-
0625デフォルトの名無しさん2013/06/24(月) 19:36:40.75
代数データ型の値に関する次の2つの更新方法は、
実行効率で違いはあるのでしょうか。

data D = D { x :: Int, y :: Int, z :: Int }
d = D 1 2 3

{方法1} d' = D 5 6 7
{方法2} d' = d { x = 5, y = 6, z = 7}

部分的に更新するのではなく、全てのフィールドの値を更新するとして、です。


GHC のバージョンは 7.6.3 です。
0626デフォルトの名無しさん2013/06/24(月) 20:44:50.76
>>625
違いはない。
コンパイルの途中で同じコードになる。
0627デフォルトの名無しさん2013/06/24(月) 21:48:17.00
>>626
ありがとうございました。
0628デフォルトの名無しさん2013/06/24(月) 22:43:19.95
>>625
不安なら、中間コードを生成して中を覗けばいいと思う
0629デフォルトの名無しさん2013/06/25(火) 12:57:13.87
>>618のコードってどういう意図なの?
0630デフォルトの名無しさん2013/06/25(火) 19:44:03.76
スタックを消費しない
0631デフォルトの名無しさん2013/06/25(火) 19:54:39.46
なんか遅延評価だと末尾再帰の効果はあんまりないみたいな話なかったっけ
うろ覚え
0632デフォルトの名無しさん2013/06/25(火) 20:22:43.95
素朴な実装だと再帰の深さ分だけサンクをヒープに作るので
メモリ消費量的には余り変わらないという話じゃない?
0633デフォルトの名無しさん2013/06/25(火) 20:34:26.43
なんか「末尾再帰化はあんま気にすんな」みたいな結論だけ見た記憶がある
実際バリバリ使ってる人達はその辺どうしてるんでしょ
0634デフォルトの名無しさん2013/06/25(火) 21:59:34.70
末尾再帰最適化はちゃんと効果あるし再帰が深くなるなら重要だよ

>>632
>素朴な実装だと再帰の深さ分だけサンクをヒープに作るので
それは末尾再帰とは直交した問題
末尾再帰にした上で、サンクを作らないようにseqや!を使えばいいだけ
0635デフォルトの名無しさん2013/06/25(火) 22:21:52.19
しかしあの当時は21世紀になっても末尾再帰化を人手でやる羽目になるとは思いもよらなんだ…
思ったより進化してないなあ
0636デフォルトの名無しさん2013/06/25(火) 22:49:05.80
末尾再帰ってどうやったら自動化できるの?
06376182013/06/26(水) 00:17:25.70
>>619
>>621
>>622

見難くないならまぁいいかな。

ご指摘の点を読み返してみて、自分はその関数がどういうものかという定義で
考えているのではなく、CやJavaのforループでカウンタと累積変数を動かしているのを
頭を使わず末尾再帰に書き下しているのだと思う。

できるだけfoldを使えるように精進するよ。
06386182013/06/26(水) 00:35:50.85
>>629
factだと自明すぎて例として不適切だったでしょうか

いちおう繰り返しを行う関数を作るときは、必要な引数を受ける名前を定義して、
内部で末尾再帰のカウンタと累積変数をもちいた定義を行うということを示したつもりでした。

これでは動かんというのならごめんなさい。
Haskell慣れてないんです。
特にwhereのかかる範囲とか。
lisp、schemeの括弧が懐かしいです。
0639デフォルトの名無しさん2013/06/26(水) 01:41:38.28
末尾再帰という言葉で十分かと
0640デフォルトの名無しさん2013/06/26(水) 06:22:49.98
末尾再帰って Wikipedia とか見てもよく分からなかったんだけど、
この間の放送大学の「データ構造とプログラミング 9 再帰」見てようやく理解した。
0641デフォルトの名無しさん2013/06/26(水) 07:21:21.31
>>639
Prologなんかだと、末尾再帰ができていない処理系は使い物にならないし、
末尾再帰を意識して書かないと、動かないこともある。Prologの場合は、
末尾以前の全てのサブゴールの決定性が問われるとか、特殊な条件が付くが、
Haskellだとどうなのか、とかの理解は必要だと思う。
0642デフォルトの名無しさん2013/06/26(水) 09:43:03.34
必ずしも再帰に限られないから、その言葉は良くない
0643デフォルトの名無しさん2013/06/26(水) 10:04:14.10
放送大学そんなコースもあるのか
06446412013/06/26(水) 17:06:31.77
末尾再帰の最適化ができていない処理系は使い物にならない。ですね。
0645デフォルトの名無しさん2013/06/26(水) 18:09:07.83
末尾呼び出し、tail callだな
0646デフォルトの名無しさん2013/06/26(水) 20:16:06.11
私は、tail callがjumpになる、という言い方を説明のためには使うけど
0647デフォルトの名無しさん2013/06/26(水) 20:35:30.04
>>646
shemeの継続?
0648デフォルトの名無しさん2013/06/26(水) 21:10:53.39
Haskell において、ある関数の定義が末尾再帰になっているかどうかをどうやって確かめる?
別の言い方をすれば、何を以って末尾再帰だと断定できる?

最後に自分自身を「呼び出す」ような形になっている、という言い方はできないよね。
関数を呼ぶのは評価が行われる時だから、引数の方が後に呼び出されるかもしれないし。
0649デフォルトの名無しさん2013/06/26(水) 23:34:33.45
Haskellはどんなプログラムを作るのに向いているのでしょうか?
C#とHaskellの使い分けの方針とかありますか?
0650デフォルトの名無しさん2013/06/26(水) 23:56:54.05
ageながら宗教色のある質問を投げ込むスタイル
0651デフォルトの名無しさん2013/06/27(木) 00:13:46.56
>>649
C# と同様に、極限まで処理速度を求められる分野以外なら何でもいい。
「言語」として向いている分野というのは特に無い。

使い分ける必要はなく、使い慣れたものを使えばいい。
0652デフォルトの名無しさん2013/06/27(木) 07:56:45.02
>>648
f x = f ...
みたいに、右辺の一番外側が自分自身を呼んでいればいい
ただし、caseとlet(や、構文糖であるifとwhere)が挟まっていてもok
f x = case x of [] -> 1; hd:tl -> f tl
みたいに

この形でなくても末尾再帰になることもあって、例えば
f x = putStrLn x >> f
だと、一番外側の呼び出しは(>>)だけど、IOモナドの(>>)ならfを一番外側で呼ぶので、
間接的に末尾再帰になる
■ このスレッドは過去ログ倉庫に格納されています