在Haskell中通过新类型(“包装类型")构建函数的惯用方式是什么? [英] What is the idiomatic way to build functions over newtypes ("wrapped types") in Haskell?

查看:62
本文介绍了在Haskell中通过新类型(“包装类型")构建函数的惯用方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let StringWrapper1 and StringWrapper2 be two types that wrap over a string (i.e. newtype StringWrapper1 = StringWrapper1 String and newtype StringWrapper2 = StringWrapper2).

现在,假设我们正在尝试构建从StringWrapper1StringWrapper2的函数.

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 Strings. 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)

问题/问题:这是惯用法吗?经常用funcfuncWrapper复制每个函数似乎很尴尬. 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中通过新类型(“包装类型")构建函数的惯用方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆