假设我有一个包含一个类型的模块:可以抽象地导入非抽象类型吗?
module My where
data L a = Nil | Cons a (L a)
模块导出的My
的具体定义,允许模式匹配等 是否有可能为另一个模块,说Client
以如下方式导入My
是抽象的,即模式匹配值被类型检查器禁止?
假设我有一个包含一个类型的模块:可以抽象地导入非抽象类型吗?
module My where
data L a = Nil | Cons a (L a)
模块导出的My
的具体定义,允许模式匹配等 是否有可能为另一个模块,说Client
以如下方式导入My
是抽象的,即模式匹配值被类型检查器禁止?
是的,你可以这样做
import My(L())
导入型而不导入任何构造函数。如果您仍然希望构造此类型的值(但不是模式匹配),则必须导入执行此构造的函数(例如,通过从My
导出这些函数或创建具有此类函数的实用程序模块)。
编辑:既然你明确提到,你想要一个型检查错误,我要指出的完整性,这不会造成Nil
和Cons
模式匹配是一种类型的检查错误,而仅仅是范围错误。
是;你只需要使用导入列表:如果您尝试编译此
module Client where
import My (L)
ok :: L Int
ok = undefined
bad :: L Int
bad = Cons 3 Nil
bad2 :: L Int -> Int
bad2 (Cons i _) = i
bad2 Nil = 0
,你会得到以下四大误区:
Client.hs:8:10: Not in scope: data constructor `Cons'
Client.hs:8:17: Not in scope: data constructor `Nil'
Client.hs:11:10: Not in scope: data constructor `Cons'
Client.hs:12:9: Not in scope: data constructor `Nil'
如果你确实想导入的构造函数,你会而是指定L(..)
或L(Cons)
来导入Cons
而不是Nil
。
对于其他一些可以使用import
语句的方法,请查看the HaskellWiki article on import
(尽管本文未提及导入数据类型及其构造函数)。
请注意,这几乎是完全相同的语法,用于* export *没有其构造函数的类型,并且只是'import My(L)'做同样的事情。 –
...另外,我提到了第二种形式,因为*由于某种原因*我一直在我的脑海中认为'import M(T)'应该等同于'import M(T(..))',而不是'导入M(T())',这是GHC相当有力地阻止了我的概念。 –
完美,谢谢大家! –