问题描述
让StringWrapper1
和StringWrapper2
是包裹字符串的两种类型(即newtype StringWrapper1 = StringWrapper1 String
和newtype StringWrapper2 = StringWrapper2
).
Let StringWrapper1
and StringWrapper2
be two types that wrap over a string (i.e. newtype StringWrapper1 = StringWrapper1 String
and newtype StringWrapper2 = StringWrapper2
).
现在,假设我们正在尝试构建从StringWrapper1
到StringWrapper2
的函数.
Now suppose we're trying to craft a function from StringWrapper1
to StringWrapper2
.
funcWrapper :: StringWrapper1 -> StringWrapper2
一方面,我们想明确地告诉我们传递给此函数的是StringWrapper1
,因此我们不希望仅将StringWrapper1
视为String
的类型同义词(导致错误,以我的经验可以证明).另一方面,在概念上构建功能时,我们仍然会以String
的方式进行思考.然后,我们要做的是首先构建func
,这样我们就不会不断地包装和拆开类型:
On the one hand, we want to be explicit that what we're passing into this function is a StringWrapper1
, so we don't want merely treat StringWrapper1
as a type synonym for String
(that leads to bugs, as my own experience can attest). On the other hand, when conceptually building the function, we are still somehow thinking in terms of String
s. What we want to do then is to first build func
which doesn't us to constantly wrap and unwrap types:
func :: String -> String
然后,我们使用func
构建funcWrapper
:
funcWrapper :: StringWrapper1 -> StringWrapper2
funcWrapper (StringWrapper1 str) = StringWrapper2 (func str)
问题/问题:这是惯用法吗?经常用func
和funcWrapper
复制每个函数似乎很尴尬. Haskell是否提供其他我想念的方式?还是应该只使用类型同义词?
Problem/Question: Is this idiomatic? It seems awkward to constantly be duplicating every function with a func
and a funcWrapper
. Does Haskell provide some other way of doing this that I'm missing? Or should I just use type synonyms?
推荐答案
正如其他人所说,您应该确保这确实是您想要做的(请参阅leftaboutabout的注释).如果是这样,您可以使用标准中的 coerce
库以在具有相同运行时表示形式的类型之间进行转换:
As others have said, you should make sure this is really what you want to do (see leftaroundabout's comment). If it is, you can use coerce
from the standard library to convert between types that have the same runtime representation:
func :: String -> String
func = ...
...
funcWrapper :: StringWrapper1 -> StringWrapper2
funcWrapper = coerce func
这篇关于在Haskell中通过新类型(“包装类型")构建函数的惯用方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!