gpt4 book ai didi

haskell - 内存和类型类

转载 作者:行者123 更新时间:2023-12-04 18:13:44 24 4
gpt4 key购买 nike

为了简单起见,我将使用这个人为设计的示例类(关键是我们从方法中派生了一些昂贵的数据):

class HasNumber a where
getNumber :: a -> Integer
getFactors :: a -> [Integer]
getFactors a = factor . getNumber

当然,我们可以对此类的实现进行内存,例如:
data Foo = Foo {
fooName :: String,
fooNumber :: Integer,
fooFactors :: [Integer]
}

foo :: String -> Integer -> Foo
foo a n = Foo a n (factor n)

instance HasNumber Foo where
getNumber = fooNumber
getFactors = fooFactors

但是,需要手动将'factors'字段添加到将成为 HasNumber实例的任何记录中,似乎有点丑陋。下一个想法:
data WithFactorMemo a = WithFactorMemo {
unWfm :: a,
wfmFactors :: [Integer]
}

withFactorMemo :: HasNumber a => a -> WithFactorMemo a
withFactorMemo a = WithFactorMemo a (getFactors a)

instance HasNumber a => HasNumber (WithFactorMemo a) where
getNumber = getNumber . unWfm
getFactors = wfmFactors

但是,这需要大量样板来将原始 a的所有其他操作提升为 WithFactorMemo a

有什么优雅的解决方案吗?

最佳答案

解决方法是:丢失类型类。我已经讨论过herehere。每个成员都将单个TC a作为参数的任何类型类a与数据类型都是同构的。这意味着HasNumber类的每个实例都可以用以下数据类型表示:

data Number = Number {
getNumber' :: Integer,
getFactors' :: [Integer]
}

即,通过这种转换:
toNumber :: (HasNumber a) => a -> Number
toNumber x = Number (getNumber x) (getFactors x)
Number显然也是 HasNumber的一个实例。
instance HasNumber Number where
getNumber = getNumber'
getFactors = getFactors'

这种同构向我们表明,此类是一种变相的数据类型,它应该消亡。只需使用 Number即可。最初如何执行此操作尚不明确,但是有一点经验后应该很快就会知道。例如,您的 Foo类型变为:
data Foo = Foo {
fooName :: String,
fooNumber :: Number
}

您的备忘将免费提供,因为这些因素存储在 Number数据结构中。

关于haskell - 内存和类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7861261/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com