Могу ли я импортировать неабстрактный тип абстрактно? - PullRequest
2 голосов
/ 25 июня 2011

Предположим, у меня есть модуль, который содержит тип:

module My where

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

Модуль экспортирует конкретное определение My, чтобы обеспечить сопоставление с образцом и т. Д. Возможно ли это для другого модуля, скажем, Clientимпортировать My таким образом, чтобы L a было абстрактным, то есть таким, чтобы сопоставление с образцом по значениям L a было запрещено средством проверки типов?

Ответы [ 2 ]

6 голосов
/ 25 июня 2011

Да;вам просто нужно использовать список импорта:

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 проверьте Статья на HaskellWiki import (хотя в статье не упоминается импорт типов данных и их конструкторов).

4 голосов
/ 25 июня 2011

Да, вы можете сделать

import My(L())

для импорта типа без импорта любого из его конструкторов. Если вы все еще хотите построить значения этого типа (но не сопоставление с образцом), вы должны импортировать функции для выполнения этой конструкции (например, экспортируя такие функции из My или создавая служебный модуль с такими функциями).

edit: Поскольку вы явно упомянули, что хотели ошибку проверки типа , я должен указать для полноты, что это не приведет к тому, что сопоставление с образцом на Nil и Cons будет ошибка проверки типов, но просто ошибка определения области видимости.

...