【问题标题】:Haskell Show type class in a functionHaskell 在函数中显示类型类
【发布时间】:2020-08-17 06:30:50
【问题描述】:

我有一个函数

mySucc :: (Enum a, Bounded a, Eq a, Show a) => a -> Maybe a
mySucc int 
     | int == maxBound = Nothing
     | otherwise = Just $ succ int

当我想在 ghci 中打印这个函数的输出时,Haskell 似乎对使用哪个 Show 实例感到困惑。这是为什么? Haskell 不应该在运行时自动解析 a 的类型并使用它的 Show 吗?

我对类型类的有限理解是,如果你提到一个类型(在我的例子中是 a)并说它属于一个类型类(Show),Haskell 应该自动解析该类型。这不就是它如何解决有界、枚举和方程式的吗?如果我的理解有误,请纠正我。

【问题讨论】:

  • 你是如何在 GHCi 中调用这个函数的?
  • 您好,是使用“stack ghci”

标签: haskell


【解决方案1】:

Haskell 不应该在运行时自动解析 a 的类型并使用它的 Show

一般来说,类型在运行时不存在。编译器对您的代码进行类型检查,解析任何多态性,然后擦除类型。但是,这与您的主要问题有点正交。

我对类型类的有限理解是,如果你提到一个类型(在我的例子中是a)并说它属于一个类型类(Show),Haskell 应该自动解析类型

没有。编译器会自动解析实例。这意味着,您不需要将显示方法显式传递到您的函数中。例如,代替函数

showTwice :: Show a => a -> String
showTwice x = show x ++ show x

你可以有一个不使用任何类型类的函数

showTwice' :: (a -> String) -> a -> String
showTwice' show' x = show' x ++ show' x

如果您将标准show 作为第一个参数,它的使用方式与showTwice 几乎相同。但是该参数需要在每个呼叫站点手动传递。 这是你可以通过使用类型类来避免,但这仍然需要首先知道类型

(您的mySucc 实际上并没有以任何方式使用show,因此您不妨完全省略Show a 约束。)

当您对mySucc 的调用出现在更大的表达式中时,很可能类型实际上也会被自动推断。比如mySucc (length "bla")会使用a ~ Int,因为length的结果固定为Int;或mySucc 'y' 将使用a ~ Char。但是,如果 all 子表达式是多态的(并且在 Haskell 中,偶数字面量是多态的),那么编译器不会有任何指示您真正想要什么类型。在这种情况下,您始终可以在参数中明确指定它

> mySucc (3 :: Int)
Just 4

或在结果中

> mySucc 255 :: Maybe Word8
Nothing

【讨论】:

  • 现在我明白了,当我们使用“test :: (Eq a) -> a -> a”时,它意味着 a 是任何实现等式中描述的所有(强制性)方法的实例。谢谢解释
  • 是的。我基本上只是意味着您将能够在test 的定义中使用==,即使您当时不知道它是什么类型。但是当test在实际程序中使用时,编译器确实需要知道类型。
【解决方案2】:

你在写mySucc 1吗?在这种情况下,您会收到错误消息,因为 1 文字是 Num a => a 类型的多态值。

尝试拨打mySucc 1 :: Maybe Int,它会起作用。

【讨论】:

    猜你喜欢
    • 2021-12-31
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多