gpt4 book ai didi

haskell - Haskell 中记录类型和子类型的当前状态

转载 作者:行者123 更新时间:2023-12-02 02:51:04 25 4
gpt4 key购买 nike

Haskell 中记录类型和子类型的当前状态是什么?

我知道已经完成了重载记录名称等方面的工作。具体来说,我想制作三种不同的记录类型 A , B , 和 C哪里BC包含与 A 相同的所有字段标签,但不要相互共享字段标签。然后,我希望能够在 f : A -> int 处编写函数, g: B -> int , h: C -> int其中函数f也接受类型为 B 的参数和 C .基本上,我想要BCA 的子类型.更具体地说,如果我不必重复所有字段标签,那就太好了。在伪代码中,这类似于

data A = A { a :: String }
data B = B { A, b :: Char }
data C = C { C, c :: Float }

f :: A/B/C -> int
g :: B -> int
h :: C -> int

最佳答案

有几种不同的方法可以实现这一点,但也有一些缺点。

以下是我正在使用的类型:

data A = A { a :: String}
data B = B { bA :: A, b :: Char}
data C = C { cA :: A, c :: Float}

Ad-hoc 多态性:所有这些类型都可以

您可以定义 f作为一些 CanF的方法类(class) A , B , 和 C都是以下情况的实例:
class CanF a where
f :: a -> Int

instance CanF A where
f = length . a

instance CanF B where
f = f . bA

instance CanF C where
f = f . cA

定义 BC的实例在 A 方面的实例清楚地表明 f在每种情况下都做同样的事情。制作很简单 f根据定义 F 的类型做不同的事情实例。这种方法的缺点是任何其他类似 f 的函数都需要添加为同一“CanSomething”类的方法。
main :: IO ()
main = do
print (f a)
print (f b)
print (f c)
where
a = A "Hello"
b = B a 'H'
c = C a 3.14

Ad-hoc 多态性:所有这些类型都可以表示为 A

另一种方法是写 f作为受类约束的函数,该类始终为您提供 A .
class RepA a where
getA :: a -> A

instance RepA A where
getA = id

instance RepA B where
getA = bA

instance RepA C where
getA = cA

f :: RepA a => a -> Int
f = length . a . getA

在这里,您定义什么的灵活性较低 f可以做,这可能是好的也可能是坏的。优点是您可以定义其他适用于 A 的函数。没有向您的类添加新方法。

功能记录

我处理这个问题的首选方法是功能记录方法。定义一个参数化数据类型,其中包含您要调用的函数。然后为您的记录类型定义专门的构造函数。这种方法的缺点是它通常更加冗长。优点是您可以通过提供不同的 F 来交换行为。到 f功能。另一个优点是您可以在不需要语言扩展的情况下完成更多工作。
data F a = F { f :: a -> Int }

af :: F A
af = F $ length . a

bf :: F B
bf = F $ f af . bA

cf :: F C
cf = F $ f af . cA

main :: IO ()
main = do
print (f af a)
print (f bf b)
print (f cf c)
where
a = A "Hello"
b = B a 'H'
c = C a 3.14

关于haskell - Haskell 中记录类型和子类型的当前状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22417063/

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