让StringWrapper1
和StringWrapper2
成为两个包装字符串的类型(即newtype StringWrapper1 = StringWrapper1 String
和newtype StringWrapper2 = StringWrapper2
)。
现在假设我们正在尝试从StringWrapper1
到StringWrapper2
构建一个函数。
funcWrapper :: StringWrapper1 -> StringWrapper2
一方面,我们希望明确传入该函数的是一个
StringWrapper1
,因此我们不希望仅将 StringWrapper1
视为 String
的类型同义词(这会导致错误,我的经验可以证明)。另一方面,在概念上构建函数时,我们仍然以某种方式考虑 String
。因此,我们要做的是首先构建 func
,以便我们不必不断地包装和解包类型:func :: String -> String
然后,我们使用
func
来构建 funcWrapper
:funcWrapper :: StringWrapper1 -> StringWrapper2
funcWrapper (StringWrapper1 str) = StringWrapper2 (func str)
问题/疑问: 这种写法是否符合惯用语?每个函数都要重复使用func
和funcWrapper
看起来很别扭。Haskell是否提供了其他方法来解决这个问题,还是我漏掉了什么?或者我应该只使用类型同义词?
GeneralizedNewtypeDeriving
通常比使用像coerce
这样的东西更好(这里的答案似乎集中在这个上面),但这取决于情况。 - Alexis King