开发者

Can I import a non-abstract type abstractly?

开发者 https://www.devze.com 2023-03-15 02:27 出处:网络
Suppose I have a module that contains a type: module My where data L a = Nil | Cons a (L a) The module exports the concrete definition of My to allow for pattern matchi开发者_C百科ng etc.

Suppose I have a module that contains a type:

module My where

data L a = Nil | Cons a (L a)

The module exports the concrete definition of My to allow for pattern matchi开发者_C百科ng etc. Is it possible for another module, say Client to import My in a manner where L a is abstract i.e. such that pattern matching on L a values is prohibited by the type-checker?


Yes; you just have to use the import list:

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

If you try to compile this, you'll get the following four errors:

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'

If you did want to import the constructors, you would instead specify L(..), or L(Cons) to import Cons but not Nil.

For some other ways you can use the import statement, check out the HaskellWiki article on import (although the article doesn't mention importing data types and their constructors).


Yes, you may do

import My(L())

to import a type without importing any of its constructors. If you still wish to construct values of this type (but not pattern match), you must import functions for doing that construction (for example, by exporting such functions from My or by creating a utility module with such functions).

edit: Since you explicitly mentioned that you wanted a type-checking error, I should point out for completeness that this won't cause pattern-matching on Nil and Cons to be a type-checking error, but merely a scoping error.

0

精彩评论

暂无评论...
验证码 换一张
取 消