5

VoidHaskell Libraries メーリングリストで議論しているときに、次のような発言がありました:

昔は、タイプが何も持つべきではないと教えてくれたときに、unsafeCoerce全体をトラバースしてその内容を置き換えるのにお金を払いたくないというコナー・マクブライドの要請で実装されていました。Functorこれは、適切な Functor に適用された場合は正しいですが、GADT が存在する場合は覆すことができます。

のドキュメントにunsafeVacuousも次のように記載されています。

タイプの値のみを保持するVoidものよりも無人である場合は、値を保持していません。FunctorVoid

これは、引数に対して GADT のような分析を実行しない有効なファンクターに対してのみ安全です。

このようないたずら好きな GADTFunctorインスタンスはどのように見えるでしょうか? (もちろんトータル機能のみを使用しundefinederrorなどは使用しません)

4

1 に答える 1

4

Functorファンクターの法則に準拠していない (しかし完全な) インスタンスを提供する意思がある場合は、確かに可能です。

{-# LANGUAGE GADTs, KindSignatures #-}

import Data.Void
import Data.Void.Unsafe

data F :: * -> * where
  C :: F Void
  D :: F a

instance Functor F where
  fmap f _ = D

wrong :: ()
wrong = case (unsafeVacuous C :: F Int) of D -> ()

wrong型チェッカーが結果を合計と見なしても、結果を評価すると実行時例外が発生するようになりました。

編集

関手性については非常に多くの議論があったため、実際にその引数の分析を実行する GADT が関手であることができない理由について、非公式の議論を追加させてください。私たちが持っている場合

data F :: * -> * where
  C :: ... -> F Something
  ...

whereは単純な変数ではない任意の型であり、有効なインスタンスを にSomething与えることはできません。ファンクターの同一性法則に従うために、関数は にマッピングする必要があります。しかし、unknown に対して ,を作成する必要があります。単純な変数以外の場合、それは不可能です。FunctorFfmapCCF bbSomething

于 2013-07-19T09:22:17.157 に答える