完全にコンパイルされる次の Haskell コードがあります。
import Control.Monad.Reader (Reader (..))
import Data.Coerce (Coercible, coerce)
data Flow i o = Flow (i -> o) (o -> i)
coerceFlow
:: (Coercible i i', Coercible o o')
=> Flow i o
-> Flow i' o'
coerceFlow = coerce
ただし、Flow
型の定義を次のように変更すると:
data Flow i o = Flow (i -> Reader Int o) (o -> i)
奇妙なエラーが表示され始めます。
Coerce.hs:10:14: error:
• Couldn't match type ‘o’ with ‘o'’ arising from a use of ‘coerce’
‘o’ is a rigid type variable bound by
the type signature for:
coerceFlow :: forall i i' o o'.
(Coercible i i', Coercible o o') =>
Flow i o -> Flow i' o'
at Coerce.hs:(6,1)-(9,17)
‘o'’ is a rigid type variable bound by
the type signature for:
coerceFlow :: forall i i' o o'.
(Coercible i i', Coercible o o') =>
Flow i o -> Flow i' o'
at Coerce.hs:(6,1)-(9,17)
• In the expression: coerce
In an equation for ‘coerceFlow’: coerceFlow = coerce
• Relevant bindings include
coerceFlow :: Flow i o -> Flow i' o' (bound at Coerce.hs:10:1)
|
10 | coerceFlow = coerce
| ^^^^^^
私が理解しているように、私のデータ型はもはやCoercible
自動的ではありません。Flow
タイプの値を自動的に強制できることを GHC に伝える方法はありますか? 各フィールドを手動で処理できますが、データ型全体を一度に処理coerce
したいと考えています (これは機能するために必要です)。coerce
DerivingVia
私はRoleAnnotations
このような拡張機能を使用してみました:
type role Flow representational representational
しかし、私はエラーが表示されます:
Coerce.hs:6:1: error:
• Role mismatch on variable o:
Annotation says representational but role nominal is required
• while checking a role annotation for ‘Flow’
|
6 | type role Flow representational representational
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^