是否可以在Purescript中对类型构造函数设置某些约束?例如:
newtype Name = Name String
-- where length of String is > 5
答案 0 :(得分:5)
正如在另一个答案中所提到的,你需要一些更高级的类型系统才能对它进行编码,所以通常实现你想要的方法是提供一个聪明的构造函数"对于newtype
然后不导出构造函数本身,这样人们只能用你想要的属性构造newtype的值:
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
答案 1 :(得分:2)
对于该约束,答案是肯定的,因为它取决于String
的值,而Purescript没有依赖类型。
在Idris(或Agda),您可以自由地执行以下操作:
data Name : Type where
Name : (s : String) -> IsTrue (length s > 5) -> Name
其中IsTrue b
是一种类型,当且仅当b
的计算结果为true时才具有值。这将完全符合您的要求。也许一些未来的Purescript版本会支持这样的事情。
答案 2 :(得分:0)
另一种解决方案是通过数据类型的代数结构强制执行约束:
data Name = Name Char Char Char Char Char String
根据您的使用情况,这可能比智能构造函数更方便和/或更有效。