タイプファミリーを理解しようとしていますが、あまり成功していません。最小限の例を次に示します。
{-# LANGUAGE TypeFamilies #-}
class Object obj where
type Unit obj :: *
unit :: Unit obj
instance (Object obj, Object obj') => Object (obj, obj') where
type Unit (obj, obj') = (Unit obj, Unit obj')
unit = (unit, unit)
意図はかなり透明だと思います(製品カテゴリを定義しようとしています)。
これは私に与えます:
objs.hs:10:10:
Could not deduce (Unit obj' ~ Unit obj1)
from the context (Object obj, Object obj')
bound by the instance declaration at objs.hs:8:10-56
NB: `Unit' is a type function, and may not be injective
The type variable `obj1' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: Unit (obj, obj')
Actual type: (Unit obj0, Unit obj1)
In the expression: (unit, unit)
In an equation for `unit': unit = (unit, unit)
In the instance declaration for `Object (obj, obj')'
タイプシグネチャを追加しようとしました:
unit = (unit :: Unit obj, unit :: Unit obj')
しかし、これは事態を悪化させるだけです。
次の変更がコンパイルされます。
{-# LANGUAGE TypeFamilies #-}
class Object obj where
type Unit obj :: *
unit :: obj -> Unit obj
instance (Object obj, Object obj') => Object (obj, obj') where
type Unit (obj, obj') = (Unit obj, Unit obj')
unit (o, o') = (unit o, unit o')
しかし、 の余分な引数は好きではありませんunit
。
引数なしを定義することは可能unit
ですか?