問題が型コンストラクタの概念とデータコンストラクタ間の混乱です。簡潔にするために、例との違いを説明します。上記式において
data Foo a = Bar [a]
、Foo
型コンストラクタとBar
データコンストラクタです。主な違いは、Foo
はハスケル型空間の値であり、Bar
はデータ空間の値であることです。タイプスペースの値はデータスペースで使用できません。その逆もあります。たとえば、コンパイラは次の式でエラーになります。
someVariable :: Bar Int
someVariable = Foo [15]
ただし、次の式は完全に有効です。
someVariable :: Foo Int
someVariable = Bar [15]
また、すべてのタイプのコンストラクタは大文字で開始する必要があります。小文字で始まるすべての型は、型コンストラクタではなく型変数と見なされます(上の定義のa
がこれの例です)。
スマートコンストラクタの導入により、この問題に別のレイヤが追加されましたが、重要なことは、スマートコンストラクタはデータコンストラクタであり、タイプコンストラクタではありませんです。 Rec
の定義では、スマートコンストラクタdomain
を型宣言のdint
フィールドに使用しようとしました。ただし、domain
は型コンストラクタではないデータコンストラクタであり、小文字であるため、Haskellコンパイラはdomain
を型変数の名前として解釈しようとしました。 Rec
型の定義にdomain
という名前の変数を指定したことがないため、コンパイラはエラーを発生させました。
Domain
のデータコンストラクタをエクスポートして、問題を解決する必要はありません。タイプ自体のみです。これは次のようにして実現できます。エクスポート定義でDomain()
含める
module Domain (
Domain(), domain,
...
) where
そのデータ構築のいずれかのDomain
型コンストラクタをエクスポートしますが、しないようにHaskellのに指示します。これにより、安全なコンストラクタで必要とする安全性が保持され、型を正しく定義できます。新しくエクスポートされたタイプをRec
の定義で使用できるようになりました。
import Domain (Domain(), domain)
data Rec = Rec
{ dint :: Domain Int
...
}
詳細については、私は強くあなたがconstructorsとsmart constructors上HaskellWikiの記事を読むことをお勧めします。
コードを含めてください。ここで何が起こっているのかを知ることは非常に難しいです。 – Kwarrtz
おそらく型と型コンストラクタが混在しているようです。しかし、私はあなたが投稿したものからは分かりません。 – Kwarrtz
@Kwarrtzがコードを追加しました。 –