4

GHCIプレリュードで>関数のタイプを見つけるために:tを使用する:

(.) :: (b -> c) -> (a -> b) -> a -> c

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

((.)(:)) :: (a -> b) -> a -> [b] -> [b]   -- (what happened here?)

単一の関数の結果は理解していますが、部分的に適用した場合は理解できません。

マップマップの種類は何ですか?このページで、代数的にこれを行う方法についての答えを見つけました。しかし、同じ方法をに適用するのに問題があり((.)(:))ます。

タイプを知りたいときの方法は((.)(:))?関数の部分適用に使用できる考え方はありますか?

前もって感謝します。

4

2 に答える 2

9

部分適用のタイプを推測する場合は、ビルディングブロックの最も一般的なタイプから始めて、作成しているタイプ間の一致を検索するのが最善の方法です。あなたが探していたタイプについて私が従った理由を説明することによって、これをより明確にしましょう。

まず、(:)混乱を避けるために、型変数の名前を変更しましょう。

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

(.) (:)に部分的に適用さ(:)(.)、最初の引数のみを提供します。これ(.)は、タイプの、の最初の引数が、および(b -> c)でインスタンス化されることを意味します(これは正しい結合法則であることを忘れないでください)。(d -> ([d] -> [d]))b == dc == ([d] -> [d])->

この型置換を全体に適用すると、部分的に適用されたもの(.)は最初の引数を失い(として修正されています(:))、結果は(再び右連想性によって)(a -> d) -> a -> ([d] -> [d])と同等になります。これは型式です。(a -> d) -> a -> [d] -> [d]あなたはghciから得ました。

于 2012-04-05T14:39:14.710 に答える
6

@Riccardoの答えを拡張するには:

  1. 型署名の対応

    (b  ->       c     )       -- first argument of (.)
    (d  ->  ([d] -> [d])       --   corresponds to type of (:)
    
  2. 置換

    (a -> b) -> a ->      c    -- rest of (.)'s type, minus first argument
    

    (a -> d) -> a -> ([d] -> [d])
    
  3. 正しい結合性

    (a -> d) -> a -> [d] -> [d]
    
于 2012-04-05T16:14:50.837 に答える