Purescript 中的新类型是否可能存在约束?
Are constraints possible for new types in Purescript?
是否可以对 Purescript 中的类型构造函数施加某些限制?例如:
newtype Name = Name String
-- where length of String is > 5
对于该约束,答案是否定的,因为它取决于 String
的值,而 Purescript 没有依赖类型。
在 Idris(或 Agda)中,您可以自由地执行以下操作:
data Name : Type where
Name : (s : String) -> IsTrue (length s > 5) -> Name
其中 IsTrue b
是一种类型,当且仅当 b
的计算结果为真时,它才有值。这将完全按照您的意愿进行。也许未来的一些 Purescript 版本会支持这些东西。
如另一个答案中所述,您需要一些更高级的类型系统才能像那样对其进行编码,因此通常实现您想要的方法是为 [= 提供 "smart constructor" 11=] 然后不导出构造函数本身,这样人们将只能用你想要的 属性 构造新类型的值:
module Names (runName, name) where
import Prelude
import Data.Maybe (Maybe(..))
import Data.String (length)
newtype Name = Name String
-- No way to pattern match when the constructor is not exported,
-- so need to provide something to extract the value too
runName :: Name -> String
runName (Name s) = s
name :: String -> Maybe Name
name s =
if length s > 5
then Just (Name s)
else Nothing
另一种解决方案是通过数据类型的代数结构强制执行约束:
data Name = Name Char Char Char Char Char String
根据您的用例,这可能比智能构造函数更方便也可能不会更高效 and/or。
是否可以对 Purescript 中的类型构造函数施加某些限制?例如:
newtype Name = Name String
-- where length of String is > 5
对于该约束,答案是否定的,因为它取决于 String
的值,而 Purescript 没有依赖类型。
在 Idris(或 Agda)中,您可以自由地执行以下操作:
data Name : Type where
Name : (s : String) -> IsTrue (length s > 5) -> Name
其中 IsTrue b
是一种类型,当且仅当 b
的计算结果为真时,它才有值。这将完全按照您的意愿进行。也许未来的一些 Purescript 版本会支持这些东西。
如另一个答案中所述,您需要一些更高级的类型系统才能像那样对其进行编码,因此通常实现您想要的方法是为 [= 提供 "smart constructor" 11=] 然后不导出构造函数本身,这样人们将只能用你想要的 属性 构造新类型的值:
module Names (runName, name) where
import Prelude
import Data.Maybe (Maybe(..))
import Data.String (length)
newtype Name = Name String
-- No way to pattern match when the constructor is not exported,
-- so need to provide something to extract the value too
runName :: Name -> String
runName (Name s) = s
name :: String -> Maybe Name
name s =
if length s > 5
then Just (Name s)
else Nothing
另一种解决方案是通过数据类型的代数结构强制执行约束:
data Name = Name Char Char Char Char Char String
根据您的用例,这可能比智能构造函数更方便也可能不会更高效 and/or。