gpt4 book ai didi

haskell - haskell如何得到 'downcast'类型接口(interface)?

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

在 oop 中,例如 java,我们只能将 super 类向下转换为 subclass,当类型实际上是子类时。

但是在 haskell 中,我们可以简单地将类型类“向下转换”为该类型类的任何实例。例如 fromInteger 返回一个 Num。从我的角度来看,它实际上是一个Int,所以它不能被“向下转换”为Float,但它可以。

Prelude System.Random> :t fromInteger a
fromInteger a :: Num a => a
Prelude System.Random> fromInteger 12 :: Int
12
Prelude System.Random> fromInteger 12 :: Float
12.0

另一个例子是将Random改成Int、Float甚至Bool

Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Int, StdGen)
Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Double, StdGen)
Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Bool, StdGen)

我们不知道 Random 实际上是什么,但我们可以将它“向下转换”为实例的类型,并且它始终 100% 有效。我不明白为什么会这样。

最佳答案

我认为您因错误地将类型类视为 OO 类并将类型继承与它们相关联而感到困惑。类型类非常不同,Haskell 中没有类型继承,顺便说一句,这根本不是弱点。您的示例实际上展示了 Haskell 的强大功能。

我们来分析一下random的定义:

random :: RandomGen g => g -> (a, g)

它有一个签名 g -> (a, g),表示它接受一些值 g 并返回一些值 a和一些与输入 g 相同类型的值,此签名中没有指定特定类型,如 IntChar agpolymorphic ,这意味着它们可以是任何类型。然后是约束部分 RandomGen g =>,它表示实际上 g 只能是具有类型类 RandomGen 实例的类型,就在我链接到的类的接口(interface)下,你会发现模块中定义的它的实例列表,它只包含 RandomGen StdGen,所以基本上我们可以看到 g 作为 StdGen。然后再看random 函数,发现它实际上被定义为类型类Random 的接口(interface)的一部分。 ,它由类型变量 a 参数化,我们已经在函数 random 的签名中遇到过,所以这意味着 Random a 对函数 random 定义的约束。另请参阅该类在其实例列表中包含 Random IntRandom DoubleRandom Bool

现在让我们回到您的示例。通过指定类型 random (mkStdGen 12)::(Bool, StdGen),您告诉编译器将 random 视为 random::StdGen -> ( Bool, StdGen),它从中简单地推导出要使用 RandomGenRandom 的哪些实例。这些实例实际上定义了函数的特定于类型的行为,这反过来又保证了任何可编译代码都有意义。

如您所见,这一切都与转换完全无关。

关于haskell - haskell如何得到 'downcast'类型接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18184719/

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