Purescript中新类型的约束是否可行?

时间:2016-01-02 19:37:27

标签: purescript

是否可以在Purescript中对类型构造函数设置某些约束?例如:

newtype Name = Name String
   -- where length of String is > 5

3 个答案:

答案 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

根据您的使用情况,这可能比智能构造函数更方便和/或更有效。