【问题标题】:Understanding 'sprint' after evaluating a polymorphic expression [duplicate]在评估多态表达式后理解“冲刺”[重复]
【发布时间】:2016-06-22 03:27:52
【问题描述】:

给定:

λ: let x = 1 + 2

我运行sprint 来打印它的值:

λ: :sprint x
x = _

正如预期的那样,它没有被评估。

但是,在评估x之后:

λ: x
3

sprint 仍然输出_,即未评估:

λ: :sprint x
x = _

为什么会这样?

【问题讨论】:

    标签: haskell polymorphism ghci thunk


    【解决方案1】:

    这是因为x 是多态的。

    比较:

    Prelude> let x = 1 + 2 :: Int
    Prelude> :sprint x
    x = _
    Prelude> x
    3
    Prelude> :sprint x
    x = 3
    Prelude>
    

    x 是多态时,GHCI 不能用特定值替换 thunk,因为您以后可能会将其评估为不同的类型。

    【讨论】:

    • 为什么多态性会影响其表达值?
    • 我认为这里的关键是带有类型类约束的“值”,例如Num a => a,并不是真正的普通值。相反,它实际上是一个从类型类字典到值的函数
    • @KevinMeredith 在不知道它是哪个函数的情况下运行 + 函数是不可能的。例如,一个复数会有两个字段,这两个字段都需要相加;该版本+ 的编译代码完全不同。当您评估x(通过在提示符处输入x)时,GHCi 必须选择一个具体类型(默认情况下;如果默认规则不适用,它将引发错误)并调用该类型的+ 版本。但是x本身就是all(Num)类型;它始终是未经评估的重击,因为您始终可以创建新的 Num 实例,然后使用 x 作为这些类型。
    • @KevinMeredith Alexis Kind 100% 正确。在 Haskell 编译期间,类型类被删除。这是通过引入明确的“字典参数”来完成的,这些参数带来了关于应该使用哪个实例的信息。所以x 变成了一个NumDict a -> a 类型的函数,其中NumDict a 类型包含a 类型的Num 操作的实现。当您尝试评估x 时,它的类型默认为Integer,因此您实际上正在执行x NumDictInteger,其中NumDictIntegerInteger 的实例声明为Num 定义。
    猜你喜欢
    • 1970-01-01
    • 2020-07-08
    • 2010-10-22
    • 2015-06-26
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多