gpt4 book ai didi

haskell - 理解单态与多态 Core 表达式

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

我想了解简单的算术表达式是如何编译到 GHC 9.0.1 Core 中的
为此,我隔离了相同的声明,

f = \x y -> sqrt x + y
并将其编译为两种不同的类型:
f :: Double -> Double -> Double

f :: Floating a => a -> a -> a
导致这些非常不同的野兽:
\ (x [Dmd=<S,1*U(U)>] :: Double) (y [Dmd=<S,1*U(U)>] :: Double) ->
case x of { D# x ->
case y of { D# y -> D# (+## (sqrtDouble# x) y) }
}
在单态情况下和
\ (@a)
($dFloating_a22t [Dmd=<S(S(S(C(C(S))LLLLLL)LLL)LLLLLLLLLLLLLLLLLLLLLL),U(1*U(1*U(1*C1(C1(U)),A,A,A,A,A,A),A,A,A),A,A,A,1*C1(U),A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A)>]
:: Floating a)
(eta_B0 :: a)
(eta_B1 :: a) ->
+ @a
($p1Fractional @a ($p1Floating @a $dFloating_a22t))
(sqrt @a $dFloating_a22t eta_B0)
eta_B1
在多态之一。
除了需求/严格注释( Dmd=... 东西),这值得一个单独的问题,我很想了解两个结果表达式的不同形状。在单态情况下,我们进行嵌套大小写匹配,但在另一种情况下,我们只看到用类型变量( @a )和约束( $p1Fractional 等)注释的运算符
我想我应该补充一点,上面的输出是通过在预先存在的 CoreToDo 列表的最后运行的自定义插件传递获得的,所以在脱糖等之后(这是我对这个主题的全部了解)
是否存在 GHC 阶段,其中这两个编译版本在结构上相同?

最佳答案

内部一个 Float是一个数据构造函数,其中一个字段包含一个原始 Float#以底层机器的格式(所以是 32 位字)。

data Float = MkFloat Float#
这是一个盒装表示,因此 Float也可能是一个重击。它的作用是一个 case表达式来评估任何 thunk 然后访问底层机器 Float# .
因此,您的函数 Float -> Float -> Float ,经过简化,编译为一个匹配参数的函数,并对基础值执行原始操作。

类型类被编译为字典。
class Floating a where
sqrt :: a -> a
...

-- becomes a record --

data Floating a = MkFloating {
sqrt :: a -> a,
... }
多态函数变成字典传递函数
Floating a => a -> a -> a
-- becomes --
Floating a -> a -> a -> a
方法调用变成了字段访问:
sqrt x
-- becomes --
sqrt floatingDict x

-- where floatingDict :: Floating a is constructed from dictionary parameters in scope and from instances (which are compiled to dictionaries or functions on dictionaries)
(注意:这有点特定于 GHC,其他编译器虽然很少见,但可能会有所不同。)

Is there a GHC stage in which these two compiled versions are structurally identical?


不,他们为什么会这样?

关于haskell - 理解单态与多态 Core 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68074565/

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