StringWrapper1StringWrapper2 是两种包装字符串的类型(即 newtype StringWrapper1 = StringWrapper1 Stringnewtype StringWrapper2 = StringWrapper2 )。

现在假设我们正在尝试制作一个从 StringWrapper1StringWrapper2 的函数。

funcWrapper :: StringWrapper1 -> StringWrapper2

一方面,我们希望明确我们传递给这个函数的是 StringWrapper1 ,所以我们不想仅仅将 StringWrapper1 视为 String 的类型同义词(这会导致错误,正如我自己的经验可以证明的那样) )。另一方面,在概念上构建函数时,我们仍然以某种方式考虑 String s。然后我们想要做的是首先构建 func ,它不需要我们不断地包装和解包类型:
func :: String -> String

然后,我们使用 func 来构建 funcWrapper :
funcWrapper :: StringWrapper1 -> StringWrapper2
funcWrapper (StringWrapper1 str) = StringWrapper2 (func str)

问题/问题: 这是惯用语吗?经常用 funcfuncWrapper 复制每个函数似乎很尴尬。 Haskell 是否提供了一些我缺少的其他方法?或者我应该只使用类型同义词?

最佳答案

正如其他人所说,您应该确保这确实是您想要做的(请参阅 leftaroundabout 的评论)。如果是,您可以使用 coerce from the standard library 在具有相同运行时表示的类型之间进行转换:

func :: String -> String
func = ...

...

funcWrapper :: StringWrapper1 -> StringWrapper2
funcWrapper = coerce func

10-06 02:44