让 StringWrapper1
和 StringWrapper2
是两种包装字符串的类型(即 newtype StringWrapper1 = StringWrapper1 String
和 newtype StringWrapper2 = StringWrapper2
)。
现在假设我们正在尝试制作一个从 StringWrapper1
到 StringWrapper2
的函数。
funcWrapper :: StringWrapper1 -> StringWrapper2
一方面,我们希望明确我们传递给这个函数的是
StringWrapper1
,所以我们不想仅仅将 StringWrapper1
视为 String
的类型同义词(这会导致错误,正如我自己的经验可以证明的那样) )。另一方面,在概念上构建函数时,我们仍然以某种方式考虑 String
s。然后我们想要做的是首先构建 func
,它不需要我们不断地包装和解包类型:func :: String -> String
然后,我们使用
func
来构建 funcWrapper
:funcWrapper :: StringWrapper1 -> StringWrapper2
funcWrapper (StringWrapper1 str) = StringWrapper2 (func str)
问题/问题: 这是惯用语吗?经常用
func
和 funcWrapper
复制每个函数似乎很尴尬。 Haskell 是否提供了一些我缺少的其他方法?或者我应该只使用类型同义词? 最佳答案
正如其他人所说,您应该确保这确实是您想要做的(请参阅 leftaroundabout 的评论)。如果是,您可以使用 coerce
from the standard library 在具有相同运行时表示的类型之间进行转换:
func :: String -> String
func = ...
...
funcWrapper :: StringWrapper1 -> StringWrapper2
funcWrapper = coerce func