1
foldr:: (a -> b -> b) -> b -> [a] -> b
map :: (a -> b) -> [a] -> [b]
mys :: a -> a
(.) :: (a -> b) -> (c -> a) -> c -> b

推測されるタイプ:
a.map mys ::
b.mys map ::
c.foldr map ::
d.foldr map.mys ::

mys n = n + 2を使用して自分で自分自身を作成し​​ようとしましたが、そのタイプは

mys :: Num a => a -> a

'Num a =>a->a'と'a->a'の違いは何ですか?または、「Num a =>」はどういう意味ですか?私のものはNumタイプだけを取るということですか?

とにかく、
a)私は[a]-> [a]を取得しました。これは、リストを取得して、私の定義に従って+2'dを返すためだと思います
b)(a-> b)-> [a] -> [b]マップはまだ(* 3)のような両方の引数を取る必要があるので、リストは[a]を返します。これはmysに行き、[b]を返します
。c)これを行う方法がわかりません
1。d )これを行う方法もわかりません1が、map.mysは、最初にmysを実行してから、正しくマップすることを意味しますか?

私の答えと考えは正しいですか?そうでない場合は、なぜですか?

ありがとう!

4

1 に答える 1

3

(更新:どうやら私の元の答えはOPにはあまり役に立ちませんでした...付録については以下の2番目のHRを参照してください。)


このような状況で本当にやりたいのは、起動してさまざまな式の種類を見つけるためにghci使用することです。:t例えば

:t foldr map
-- answer: foldr map :: [b] -> [b -> b] -> [b]

最初に名前を定義する必要がある場合は、次を使用しますlet(Haskellソースファイルでは必要ありません)。

let mys = undefined :: a -> a
:t map mys
-- answer: [a] -> [a]

undefined明示的な型シグニチャーでの使用に注意してください。さまざまな形式の式のタイプを見つけるのに完全に問題はなく、計画の初期段階でプレースホルダーとして実際のコードで役立つ場合もあります。

は;Num a =>の型クラス制約です。a詳細については 、「A Gentle Introduction to Haskell、Version98」または第6章「RealWorldHaskell 」の型クラスの使用などの型クラスとオーバーロードを参照してください。(基本的に、それはあなたが思うことをします。:-))


上記はあなたの答えを確認するのに役立つはずです(そして型クラスのリソースは良いです)。この種の問題を自分で解決する方法については、次のようになります。

型推論は、いわゆる「統合アルゴリズム」のアプリケーションです。多くのリソースの「統一」のためのグーグル。プログラミング言語の名前をクエリに追加すると、実装例が見つかる可能性があります。

手元の例へのアプローチ方法については...

a。map mysmap型の関数を受け取り、型a -> bの関数を返します[a] -> [b]。一般に、aとは異なる場合bmysありますが、タイプa -> aはであるため、返される関数はタイプになり[a] -> [a]ます。

ここにいくつかの手による統一があります:

(a -> b) -> [a] -> [b]`  
(a -> a)`
      ^-- at this point we unify a with b;
          when propagated to the return type,
          this produces [a] -> [a]

b。mys mapmysは、あるタイプのオブジェクトを受け取り、同じタイプのオブジェクトを返す関数です。特に、型の引数を渡すと、それ(a -> b) -> [a] -> [b]が戻り値の型になります。

undefinedちなみに、型シグネチャがa -> a(型クラスの制約なしで)である「興味深い」(ではない)関数は1つだけです。つまり、idです。フィリップ・ワドラーの論文「Theorems forfree!」を参照してください。(このページからダウンロードできます)詳細な説明があります。

c。:まず、の署名のsとsは、の署名のsとsとは何の関係もないことfoldr mapに注意してください。の名前をtoとtoに変更し、署名を使用して、これを以下でより簡単に明らかにするのが便利な場合があります。また、これはより簡単な記述方法であることに注意してください。abfoldrmapmapacbdmap :: (c -> d) -> [c] -> [d](a -> b -> b)(a -> (b -> b))

より多くの手による統一(説明は以下に続きます):

(a       -> (b  -> b))
(c -> d) -> [c] -> [d]

ここで何が起こるかというと、それfoldrは型の関数引数を取るということ(a -> (b -> b))です。mapその引数として渡すと、は、、 with 、そして再びwithでa統合されます。これは、に等しいことを意味します。c -> db[c][d]cd

の戻り値のfoldrタイプはb -> [a] -> b;です。前の段落で取得したより具体的なタイプを置き換えると、

[c] -> [c -> c] -> [c]
             ^-- c equals d, right?

は、 ;cの変更された署名に由来します。mapオリジナルbで、これは

[b] -> [b -> b] -> [b]

d。foldr map . mys:これは実際(foldr map) . mysにはそうではありませんfoldr (map . mys)-関数適用(「見えない演算子」)は最強をバインドします!組み合わせるa。およびc。これを解決するために上から、読者への練習として残されています。;-)

于 2010-05-11T21:16:57.907 に答える