6

ghci からの次の出力を見てください。

Prelude> :t Data.Map.lookup
Data.Map.lookup :: Ord k => k -> Data.Map.Map k a -> Maybe a
Prelude> :t flip Data.Map.lookup
flip Data.Map.lookup :: Ord a => Data.Map.Map a a1 -> a -> Maybe a1
Prelude> let look = flip Data.Map.lookup
Loading package array-0.3.0.2 ... linking ... done.
Loading package containers-0.4.0.0 ... linking ... done.
Prelude> :t look
look :: Data.Map.Map () a -> () -> Maybe a

lookの推定型が の型と異なるのはなぜflip Data.Map.lookupですか?


あなたにいくつかの文脈を与えるために。最初は小さなプログラムがあり、コンパイラエラーが発生する理由を理解しようとしていました:

import qualified Data.Map as M

type A = String
type B = String
data C = C1 | C2 | C3
     deriving (Eq, Ord)
type D = String

z :: A -> M.Map A B -> M.Map B C -> M.Map C D -> Maybe D
z a aToB bToC cToD = look aToB a >>= look bToC >>= look cToD
  where look = flip M.lookup

Ghci の反応:

Prelude> :load main.hs
[1 of 1] Compiling Main             ( main.hs, interpreted )
Failed, modules loaded: none.

main.hs:10:52:
    Couldn't match expected type `C' with actual type `[Char]'
    Expected type: C -> Maybe D
      Actual type: A -> Maybe a0
    In the return type of a call of `look'
    In the second argument of `(>>=)', namely `look cToD'

このバリエーションはうまくコンパイルできることがわかりました (型定義は同じです)。

x :: A -> M.Map A B -> M.Map B C -> Maybe C
x a aToB bToC = look aToB a >>= look bToC
  where look = flip M.lookup

y :: A -> M.Map A B -> M.Map B C -> M.Map C D -> Maybe D
y a aToB bToC cToD = (x a aToB bToC) >>= look cToD
  where look = flip M.lookup

そして、いくつかの実験の後、 type of をlook明示的に配置すると、最初のバージョンもうまくコンパイルされることが判明しました。

z :: A -> M.Map A B -> M.Map B C -> M.Map C D -> Maybe D
z a aToB bToC cToD = look aToB a >>= look bToC >>= look cToD
  where look :: (Ord a) => M.Map a b -> a -> Maybe b
        look = flip M.lookup

それが私の最初の質問につながります。

4

1 に答える 1

7

デフォルトでは、明示的な型指定子が指定されていない限り、最上位バインディングは非ポリモーフィックです。これは「単型性制限」として知られています。型指定子が指定されていないため、GHC はk関数を定義した時点でインスタンス化する方法を選択する必要がありました。たまたま選んだk = ()

この背後にある考え方は、ポリモーフィズムが最終的にコンパイルされたコードに多くの vtable 呼び出しを導入することによってパフォーマンスを低下させる可能性があるということです。特に明記されていない限り、コンパイル時にこれらを強制的に解決することにより、このオーバーヘッドを回避できます。この決定はかなり物議を醸しています。GHC は、を渡すことにより、単型性の制限を完全に無効にする拡張機能-XNoMonomorphismRestrictionをサポートしています。

于 2011-07-31T02:56:44.673 に答える