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。