2012-03-30 25 views
5

次の方程式はMiranda Syntaxで書かれていますが、MirandaとHaskellの類似点のために、私はHaskellのプログラマが理解するはずです。関数型プログラミングにおける関数の型の決定

次の関数を定義する場合:

rc v g i = g (v:i) 
rn x = x 
rh g = hd (g []) 


f [] y = y 
f (x:xs) y = f xs (rc x y) 

g [] y = y 
g (x:xs) y = g xs (x:y) 

あなたは機能の種類を仕事はどうすればよいですか?私はf、g、rnの仕組みを理解していると思いますが、部分的なアプリケーション部分については混乱しています。

rnがあることを行っている* - > *か何か - >何でも、私はそれがだと思う - Haskellでは> A?)、fとgの場合

関数型の両方です[*] - > * - > *

私はrcとrhの型を探す方法には不明です。 rcでは、gは変数iに部分的に適用されているので、これがiの型を制約すると推測しています[*]。 rcの定義に適用されるrcとgの順序は何ですか? gはiに適用され、結果関数はrcの引数として使用されますか?あるいは、rcはv、g、iの3つの別々のパラメータを取るか?私は本当に混乱しています..どんな助けもありがとう!みんなありがとう。

申し訳ありませんが、そのHDを追加するのを忘れリストのための標準的なヘッド機能であり、以下のように定義されています。型はすでにタイプで知られており、どのように表現が定義で使用されているものから推測される

hd :: [*] -> * 
hd (a:x) = a 
hd [] = error "hd []" 
+0

この宿題はありますか? –

+0

いいえ、私は今試験の準備をしています。それはMiranda試験の古い試験問題です。 – user1058210

+0

'hd'関数の種類は何ですか? –

答えて

6

のでrc :: a -> b -> c -> d

rc v g i = g (v : i) 

、の上部に始めましょう、我々はおよそa, b, cdを知ることができるかを見る必要があります。右側に(v : i)が表示されますので、v :: aではi :: [a],c = [a]と表示されます。その後gv : iに適用されるので、g :: [a] -> d、完全に、

rc :: a -> ([a] -> d) -> [a] -> d 

rn x = x

rnの引数の型に制約ませんし、その戻り値の型は、 rn :: a -> a同じであることを意味しています。 rhの引数 gはRHSの空のリストに適用されているので

rh g = hd (g []) 

、それはタイプ[a] -> bを持っている必要があり、おそらくより多くの情報を約aまたはb続きます。実際、g []はRHS上hdのでg [] :: [c]g :: [a] -> [c]の引数は、最初の引数がリストされ、それが空の場合、結果は、したがって

rh :: ([a] -> [c]) -> c 

、次に

f [] y = y 
f (x:xs) y = f xs (rc x y) 

あります第2引数であるので、最初の式からはf :: [a] -> b -> bが続きます。さて、2番目の式では、RHSでは、fの2番目の引数はrc x yであるため、rc x yのタイプはyでなければなりません。bとなります。しかし、

rc :: a -> ([a] -> d) -> [a] -> d 

b = [a] -> dです。したがって

f :: [a] -> ([a] -> d) -> [a] -> d 

最後に

g [] y = y 
g (x:xs) y = g xs (x:y) 

我々はg :: [a] -> b -> bを推測最初の方程式から。私たちは、このように

g :: [a] -> [a] -> [a] 
+0

ダニエルありがとう!最初の方程式rcを使って、タイプ[a]として識別されたiにgを適用しますが、関数の出力がタイプdであることをどのように知ることができますか? rcの出力だけではなく、必ずしもgの出力ではないでしょうか? – user1058210

+0

'r'の定義から' g'の結果の型について何も知らないので、渡された引数 'g'の結果の型が何であれ、その呼び出しの中の' rc'の結果の型です。何でもかまいませんが、 'd'や' simon'と呼ばれるタイプ変数は重要ではありません。ここでは 'a'と呼んではいけません。これは既に別の型に使われているからです(しかし、' g1 :: [b] - > b'を渡すのは合法ですが、 'd'型は' a'しかし、それは必要ではないので、異なる表記を得る)。私は 'd'を残しました。なぜなら、これは' rc'の型の最初の近似の結果の型であったからです。 –

+0

rcの結果が単に別のg関数である場合、なぜrcの出力は[a] - > dとして与えられないのですか? rc :: a - >([a] - > d) - > [a] - >([a] - > d) – user1058210

6

、第二にgの最初の引数と短所、それの頭を取るため、第二から、我々は、b = [a]を推測私は種類を書くためにHaskellの構文を使用するつもりです。その種類はa -> b -> c -> dのようなものになりますので、ここでrc

rc v g i = g (v:i) 

は、3つのパラメータを取ります。 v:iは、viと同じタイプの要素のリストである必要があります。したがって、v :: ai :: [a]の要素のリストである必要があります。 gがそのリストに適用されるので、g :: [a] -> dです。 まとめておけばrc :: a -> ([a] -> d) -> [a] -> dとなります。

あなたはすでにrn :: a -> aを見つけたので、それは単なるIDです。

rhで使用しているhd関数の種類についてはわかりません。その点を省略します。

ここ
f [] y = y 
f (x:xs) y = f xs (rc x y) 

f 2つのパラメータを取りますので、その種類はa -> b -> cのようなものになります。 最初のケースからは、yを返すので、b == cと推測できます。最初の引数はリストです。 今のところ我々はf :: [a'] -> b -> bを知っています。 xyrcへの入力に与えられている方法を第二ケース通知に :(それはfのその2番目の引数として渡されるので、yのものもでなければならないタイプ)y機能[a'] -> d、及びrc x y :: a' -> dでなければなりません。 最後に、f :: [a'] -> ([a'] -> d) -> ([a'] -> d)と言うことができます。 ->は右結合であるため、[a'] -> ([a'] -> d) -> [a'] -> dに相当します。

残りのものについても同様の理由で理由を付けることができます。

+0

'hd'はMiranda標準ライブラリのものです。 Haskellの 'head'に相当するので、その型は' [a] - > a'です。 – hammar

+0

ありがとうリカルド!ダニエルに尋ねた質問をあなたの答えにも当てはめることができますか - ありがとう! – user1058210

+0

喜び。すみません、私は遅く到着しました。彼はすでにあなたを説明した:) –

関連する問題