コンストラクター内とコンストラクター外のforall数量詞の違い

happycoder97
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ExistentialQuantification #-}

import Data.Proxy

data Foo = FooA | FooB

class Bar (a :: k) where
    bar :: Proxy a -> Int

instance Bar FooA where
    bar _ = 1

instance Bar FooB where
    bar _ = 2

foo1 :: forall (a :: Foo). Proxy a -> (Bar a => Proxy a)
foo1 p = p

data BarProxy = BarProxy (forall a. Bar a => Proxy a)

foo2 :: forall (a :: Foo). Proxy a -> BarProxy
foo2 p = BarProxy (foo1 p)

main = print "Hello World"

このコードでは:

  1. しないfoo1、任意のProxy a場所a種類のものであるがFoo、返すProxy aようaにインスタンスを持っているのBar
  2. ていないBarProxyコンストラクタ任意の受け入れProxy a、どこaのインスタンスを持っているのBarそれはどう違うのdata BarProxy = forall a. BarProxy (Bar a => Proxy a)ですか?
  3. foo2 p = BarProxy (foo1 p)以下のエラーで失敗するのはなぜですか?
Test6.hs:27:20: error:
    • Couldn't match type ‘a1’ with ‘a’
      ‘a1’ is a rigid type variable bound by
        a type expected by the context:
          forall (a1 :: Foo). Bar a1 => Proxy a1
        at Test6.hs:27:10-26
      ‘a’ is a rigid type variable bound by
        the type signature for:
          foo2 :: forall (a :: Foo). Proxy a -> BarProxy
        at Test6.hs:26:1-46
      Expected type: Proxy a1
        Actual type: Proxy a
    • In the first argument of ‘BarProxy’, namely ‘(foo1 p)’
      In the expression: BarProxy (foo1 p)
      In an equation for ‘foo2’: foo2 p = BarProxy (foo1 p)
    • Relevant bindings include
        p :: Proxy a (bound at Test6.hs:27:6)
        foo2 :: Proxy a -> BarProxy (bound at Test6.hs:27:1)
   |
27 | foo2 p = BarProxy (foo1 p)
   |                    ^^^^^^
細山
  1. いいえ。私の理解では、の署名はfoo1と同じですforall (a :: Foo). Bar a => Proxy a -> Proxy a(ドキュメントは見つかりませんでしたが)。ghciでは、:t foo1を与えfoo1 :: Bar a => Proxy a -> Proxy aます。任意のProxy a場所a種類のものであるFooとのインスタンスをBar、それが返されますProxy a

  2. いいえ。コンストラクターにBarProxyはランク2のポリモーフィック型があり(forall a. Bar a => Proxy a) -> BarProxyます。引数はこの手段pに渡すことができるBarProxy場合にのみ、pタイプがあるProxy aため、すべてのタイプaのインスタンスですBar存在記号が必要な場合は、次のように記述できます。

    data BarProxy = forall a. Bar a => BarProxy (Proxy a)
    

    または

    data BarProxy where
      BarProxy :: forall a. Bar a => Proxy a -> BarProxy
    

    -XGADTs有効。

    実存型とユニバーサルBarProxy型を呼びましょう存在記号の場合、引数のまたは(存在記号で)のいずれかである必要があります一方、全称記号の場合は、(同じセットで全称記号)の両方入力する必要があります。以下の3つのプロキシについて考えてみましょう。forall a. Bar a => Proxy a -> BarProxy BarProxy(forall a. Bar a => Proxy a) -> BarProxy BarProxyp Proxy FooA Proxy FooB{a | a is an instance of Bar} = {FooA,FooB}p Proxy FooA Proxy FooB

    proxyFooA :: Proxy FooA
    proxyFooA = Proxy
    
    proxyFooB :: Proxy FooB
    proxyFooB = Proxy
    
    proxyPoly :: forall a. Proxy a
    proxyPoly = Proxy
    

    ExistentialBarProxyは3つのうちのいずれかを受け入れますが、Universal1はのみを受け入れますproxyPoly

  3. foo2 p = BarProxy (foo1 p)実存のためにコンパイルしBarProxyます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

コンストラクター内とコンストラクター外での宣言の違い

分類Dev

コンストラクター内とコンストラクター外でのReact状態の宣言

分類Dev

dartクラスのコンストラクターの違い

分類Dev

コンストラクター "className()とclassName ._()の使用の違い

分類Dev

コンストラクター関数とコンストラクターリテラルの違い

分類Dev

コンストラクター関数とコンストラクターリテラルの違い

分類Dev

Box <T>コンストラクターとRefCell <T>コンストラクターの動作の違い

分類Dev

スコープ外のデータコンストラクタ

分類Dev

ビルダーパターンとコンストラクターの違い

分類Dev

コンストラクター内の同期セクションと同期コンストラクターの違い

分類Dev

コンストラクター内のクラス名のテンプレートパラメーターの追加と省略の違い

分類Dev

クラス宣言v / sコンストラクター内のオブジェクトの初期化の違い

分類Dev

HMACSHA512コンストラクターとファクトリの違い

分類Dev

コンストラクターパターンとプロトタイプパターンの違い

分類Dev

継承、コンストラクターなどの抽象クラスと具象クラスの違い

分類Dev

コンストラクターの違い

分類Dev

C ++ 11コンストラクター(中括弧)の違い

分類Dev

データコンストラクターを使用したコンテキストでのforall

分類Dev

fstreamコンストラクターとopen関数の使用の違い

分類Dev

変数のinとoutコンストラクター関数の違い

分類Dev

古いスタイルと新しいスタイルのPHPコンストラクターの違い

分類Dev

本文とコンストラクターの変数設定のタイプスクリプトの違い

分類Dev

コピーコンストラクタと移動セマンティクスのC ++の違い

分類Dev

AndroidコンストラクターとonCreate()の違いは何ですか?

分類Dev

ProxyコンストラクターとReflectの違いは何ですか?

分類Dev

moveコンストラクターと 'Derived(Base &&)'コンストラクターを含むgccとclangのオーバーロード解像度の違い

分類Dev

インスタンス初期化子とコンストラクターの違いは何ですか?

分類Dev

クラスコンストラクターの呼び出しとClass.forName()。newInstanceの使用の違い

分類Dev

C#でのコンストラクターのオーバーロードとチェーンの違い

Related 関連記事

  1. 1

    コンストラクター内とコンストラクター外での宣言の違い

  2. 2

    コンストラクター内とコンストラクター外でのReact状態の宣言

  3. 3

    dartクラスのコンストラクターの違い

  4. 4

    コンストラクター "className()とclassName ._()の使用の違い

  5. 5

    コンストラクター関数とコンストラクターリテラルの違い

  6. 6

    コンストラクター関数とコンストラクターリテラルの違い

  7. 7

    Box <T>コンストラクターとRefCell <T>コンストラクターの動作の違い

  8. 8

    スコープ外のデータコンストラクタ

  9. 9

    ビルダーパターンとコンストラクターの違い

  10. 10

    コンストラクター内の同期セクションと同期コンストラクターの違い

  11. 11

    コンストラクター内のクラス名のテンプレートパラメーターの追加と省略の違い

  12. 12

    クラス宣言v / sコンストラクター内のオブジェクトの初期化の違い

  13. 13

    HMACSHA512コンストラクターとファクトリの違い

  14. 14

    コンストラクターパターンとプロトタイプパターンの違い

  15. 15

    継承、コンストラクターなどの抽象クラスと具象クラスの違い

  16. 16

    コンストラクターの違い

  17. 17

    C ++ 11コンストラクター(中括弧)の違い

  18. 18

    データコンストラクターを使用したコンテキストでのforall

  19. 19

    fstreamコンストラクターとopen関数の使用の違い

  20. 20

    変数のinとoutコンストラクター関数の違い

  21. 21

    古いスタイルと新しいスタイルのPHPコンストラクターの違い

  22. 22

    本文とコンストラクターの変数設定のタイプスクリプトの違い

  23. 23

    コピーコンストラクタと移動セマンティクスのC ++の違い

  24. 24

    AndroidコンストラクターとonCreate()の違いは何ですか?

  25. 25

    ProxyコンストラクターとReflectの違いは何ですか?

  26. 26

    moveコンストラクターと 'Derived(Base &&)'コンストラクターを含むgccとclangのオーバーロード解像度の違い

  27. 27

    インスタンス初期化子とコンストラクターの違いは何ですか?

  28. 28

    クラスコンストラクターの呼び出しとClass.forName()。newInstanceの使用の違い

  29. 29

    C#でのコンストラクターのオーバーロードとチェーンの違い

ホットタグ

アーカイブ