是否有类似`fromNewtype之类的操作的简写形式. F . toNewtype`? [英] Is there a shorthand for operations like `fromNewtype . f . toNewtype`?

查看:83
本文介绍了是否有类似`fromNewtype之类的操作的简写形式. F . toNewtype`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过newtype引入类型安全性越高的模式越多地出现,那就是将值(或多个值)投射到newtype包装器中,执行一些操作,然后缩回投影.一个普遍存在的例子是SumProduct mono半群的例子:

A pattern that presents itself the more often the more type safety is being introduced via newtype is to project a value (or several values) to a newtype wrapper, do some operations, and then retract the projection. An ubiquitous example is that of Sum and Product monoids:

λ x + y = getSum $ Sum x `mappend` Sum y
λ 1 + 2
3

我想像withSumwithSum2等功能的集合可能会针对每个newtype自动推出.或者,可能会创建参数化的Identity,以与ApplicativeDo一起使用.也许还有其他我想不到的方法.

I imagine a collection of functions like withSum, withSum2, and so on, may be automagically rolled out for each newtype. Or maybe a parametrized Identity may be created, for use with ApplicativeDo. Or maybe there are some other approaches that I could not think of.

我想知道是否存在一些现有技术或理论.

I wonder if there is some prior art or theory around this.

PS  我对coerce不满意,有两个原因:

P.S.   I am unhappy with coerce, for two reasons:

  • 安全 我以为不是很安全.在指出它实际上是安全的之后,我 尝试了几件事,但我却无济于事,因为它需要类型注释 当有歧义的可能性时.例如:

  • safety   I thought it is not very safe. After being pointed that it is actually safe, I tried a few things and I could not do anything harmful, because it requires a type annotation when there is a possibility of ambiguity. For example:

λ newtype F = F Int deriving Show
λ newtype G = G Int deriving Show
λ coerce . (mappend (1 :: Sum Int)) . coerce $ F 1 :: G
G 2
λ coerce . (mappend (1 :: Product Int)) . coerce $ F 1 :: G
G 1
λ coerce . (mappend 1) . coerce $ F 1 :: G
...
    • Couldn't match representation of type ‘a0’ with that of ‘Int’
        arising from a use of ‘coerce’
...

但是我仍然不欢迎coerce,因为剥离安全标签太容易了, 一旦达到习惯,就开枪射击某人.想象一下,在密码学中 在应用程序中,有两个值:x :: Prime Intx' :: Sum Int.我宁愿 每次使用它们时,键入getPrimegetSum都会比coerce一切都要好一天 犯了灾难性的错误.

But I would still not welcome coerce, because it is far too easy to strip a safety label and shoot someone, once the reaching for it becomes habitual. Imagine that, in a cryptographic application, there are two values: x :: Prime Int and x' :: Sum Int. I would much rather type getPrime and getSum every time I use them, than coerce everything and have one day made a catastrophic mistake.

有用性  coerce对于速记的作用不大 某些操作.我的帖子的主要示例,我在这里重复:

usefulness   coerce does not bring much to the table regarding a shorthand for certain operations. The leading example of my post, that I repeat here:

λ getSum $ Sum 1 `mappend` Sum 2
3

—变成了与这个尖刺怪兽相似的东西:

— Turns into something along the lines of this spiked monster:

λ coerce $ mappend @(Sum Integer) (coerce 1) (coerce 2) :: Integer
3

—几乎没有任何好处.

— Which is hardly of any benfit.

推荐答案

通过将求和数放入列表中并使用

Your "spiked monster" example is better handled by putting the summands into a list and using the ala function available here, which has type:

ala :: (Coercible a b, Coercible a' b') 
    => (a -> b) 
    -> ((a -> b) -> c -> b')   
    -> c 
    -> a' 

其中

  • a is the unwrapped base type.
  • b is the newtype that wraps a.
  • a -> b is the newtype constructor.
  • ((a -> b) -> c -> b') is a function that, knowing how to wrap values of the base type a, knows how to process a value of type c (almost always a container of as) and return a wrapped result b'. In practice this function is almost always foldMap.
  • a' the unwrapped final result. The unwrapping is handled by ala itself.

在您的情况下,它将类似于:

in your case, it would be something like:

ala Sum foldMap [1,2::Integer]

可以通过coerce以外的其他方式来实现

"ala"功能,例如,

"ala" functions can be implemented through means other than coerce, for example using generics to handle the unwrapping, or even lenses.

这篇关于是否有类似`fromNewtype之类的操作的简写形式. F . toNewtype`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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