通过引入类型安全性越多,这种模式就越频繁地出现newtype
是要投射一个价值(或几个值) to a newtype
包装器,做一些操作,然后收回投影。一个普遍存在的例子是Sum
and Product
幺半群:
λ x + y = getSum $ Sum x `mappend` Sum y
λ 1 + 2
3
我想象一个函数的集合,例如withSum
, withSum2
等等,可以自动为每个推出newtype
。或者也许是参数化的Identity
可以创建,用于与ApplicativeDo
。或者也许还有其他一些我想不到的方法。
我想知道是否有一些相关的现有技术或理论。
P.S.我不满意coerce
,有两个原因:
-
safety我认为这不是很安全。在被指出它实际上是安全的之后,我
尝试了一些事情,但我无法做任何有害的事情,因为它需要类型注释
当有可能出现歧义时。例如:
λ 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 Int
and x' :: Sum Int
。我宁愿
类型getPrime
and getSum
每次我使用它们时,比coerce
一切都有一天
犯了一个灾难性的错误。
-
用处 coerce
并没有带来太多关于速记为了
某些操作。我在这里重复一下我的帖子的主要示例:
λ getSum $ Sum 1 `mappend` Sum 2
3
— 变成类似这个尖刺怪物的东西:
λ coerce $ mappend @(Sum Integer) (coerce 1) (coerce 2) :: Integer
3
——这没有任何好处。
通过将加数放入列表并使用ala
功能可用here http://hackage.haskell.org/package/coercible-utils-0.0.0/docs/CoercibleUtils.html#v:ala,其类型为:
ala :: (Coercible a b, Coercible a' b')
=> (a -> b)
-> ((a -> b) -> c -> b')
-> c
-> a'
where
-
a
is the 展开的基础类型。
-
b
是包装的新类型a
.
-
a -> b
是新类型构造函数。
-
((a -> b) -> c -> b')
是一个函数,知道如何包装基本类型的值a
,知道如何处理类型的值c
(几乎总是一个容器a
s) 并返回包装结果b'
。在实践中,这个函数几乎总是foldMap http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Foldable.html#v:foldMap.
-
a'
the 展开的最后结果。展开是由处理的ala
itself.
在你的情况下,它会是这样的:
ala Sum foldMap [1,2::Integer]
“ala”功能可以通过其他方式实现coerce
, 例如使用泛型 http://hackage.haskell.org/package/newtype-generics-0.5.3/docs/Control-Newtype-Generics.html#v:ala处理展开,甚至lenses http://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Wrapped.html#v:ala.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)