2016-04-23 4 views
0

スマートコンストラクタを使用しているため、フィールドの1つにエクスポートされない型があるレコードを作成しようとしています。型としてスマートコンストラクタを使用しても機能しません。スマートコンストラクタのみを持つレコード構文フィールド型注釈

Not in scope: type variable `domain' 

多分、このようなことができる言語拡張がありますか?

コンストラクタをスマートコンストラクタとともにエクスポートすると、この問題を解決できますが、スマートコンストラクタが許可しない値を作成する可能性があります。

私が今持っている(非稼働)コード:ここ

import Domain (domain) -- Domain is not exported, and domain is a smart constructor for Domain 

data Rec = Rec 
    { dint :: domain Int -- what do I do here? I want it to be `Domain Int` but `Domain` isn't exported. 
    ... 
    } 
+0

コードを含めてください。ここで何が起こっているのかを知ることは非常に難しいです。 – Kwarrtz

+0

おそらく型と型コンストラクタが混在しているようです。しかし、私はあなたが投稿したものからは分かりません。 – Kwarrtz

+0

@Kwarrtzがコードを追加しました。 –

答えて

5

問題が型コンストラクタの概念とデータコンストラクタ間の混乱です。簡潔にするために、例との違いを説明します。上記式において

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 
    ... 
    } 

詳細については、私は強くあなたがconstructorssmart constructors上HaskellWikiの記事を読むことをお勧めします。

+0

私が正しく理解していて、確かに質問をしていないかもしれませんが、そのタイプ自体は輸出されていないと思います。その場合、彼は確かに問題があり、タイプをエクスポートしたり、図書館の著者に問題を提出する必要があります。それは初めてではないでしょう。 –

関連する問題