型レベルプログラミング

Proxy 型の代わり

symbolValtypeRep は以下のような型になっている

symbolVal :: forall n proxy. KnownSymbol n => proxy n -> String
typeRep :: forall proxy a. Typeable a => proxy a -> TypeRep

proxy 型ではなく proxy という型変数であれば何でも使える。実際には以下のように使う。

λ> symbolVal (Proxy @"abc")
"abc"

ここで symbolValproxyMaybe を使おうとすると問題が発生する

λ> symbolVal (Nothing @"abc")

<interactive>:203:21: error:
     Expected a type, but "abc" has kind Symbol
     In the type "abc"
      In the first argument of symbolVal, namely (Nothing @"abc")
      In the expression: symbolVal (Nothing @"abc")

これは Maybe 型に Just コンストラクタが含まれるためである。

data Maybe a where
  Just    :: a -> MyMaybe a
  Nothing :: MyMaybe a

a :: Symbol というカインドがつくため、(->) :: Type -> Type -> Type とカインドが合わないことが問題。

コンパイルを通すために Proxy a に変更した
data Maybe a where
  Just    :: Proxy a -> MyMaybe a
  Nothing :: MyMaybe a

よって、カインドが Type の場合は Maybe[] でも代用可能だが、それ以外の場合は Proxy を使うことになる

参考リソース

Last updated