haskell - 在 Haskell 中推导是什么/意味着什么?

标签 haskell functional-programming deriving

堆栈溢出推导的定义是:

"In Haskell, a derived instance is an instance declaration that is generated automatically in conjunction with a data or newtype declaration. The body of a derived instance declaration is derived syntactically from the definition of the associated type."



老实说,我真的不明白其中的任何一个。

以下代码摘自:Link
data BaseballPlayer = Pitcher 
                        | Catcher
                        | Infielder
                        | Outfielder
                        deriving Show

barryBonds :: BaseballPlayer -> Bool
barryBonds Outfielder = True

barryInOf = print(barryBonds Outfielder)

我的问题是,派生语句在这种特定情况下做了什么,
以及派生语句一般做什么?

最佳答案

简而言之:
deriving自动实现一些 Haskell 类型类的函数,例如 ShowEq .这不能用任意类型类来完成,但 deriving确实工作很简单,可以自动实现。
Show typeclass 定义了如何将数据类型表示为 String 的函数.

更广泛:

你熟悉类型类吗?

https://www.haskell.org/tutorial/classes.html

类型类类似于 Java 中的接口(interface):它们定义了一些函数,任何想要使用这些函数的数据类型都可以实现这些函数。

例如,假设我们有一个这样的类:

class Comparable a where
    lessThan :: a -> a -> Bool
    equalsTo :: a -> a -> Bool

当心 class 这个词.它意味着 Haskell 设置中的类型类,而不是您在面向对象语言中听到的典型“类”。 a这是一种填充类型,类似于您期望模板在 C++ 中的工作方式和泛型在 Java 中的行为方式。

假设我们定义一个数据类型如下:
data Color = Red | Green | Blue

制作 ComparableColor 合作,我们实现了 instanceComparable :
instance Comparable Color where
    lessThan Red   Green = True
    lessThan Red   Blue  = True
    lessThan Green Blue  = True
    lessThan _     _     = False

    equalsTo Red   Red   = True
    equalsTo Green Green = True
    equalsTo Blue  Blue  = True
    equalsTo _     _     = False

粗略地说,这现在允许您“比较”Red , Green , 和 Blue彼此。但是有什么方法可以让 GHC 自动猜到这就是您想要的确切“顺序”?

退后一步,类型类 Show有类似的结构:

https://hackage.haskell.org/package/base-4.9.1.0/docs/src/GHC.Show.html#Show
class  Show a  where
    showsPrec :: Int -> a -> ShowS
    show      :: a   -> String
    showList  :: [a] -> ShowS

    showsPrec _ x s = show x ++ s
    show x          = shows x ""
    showList ls   s = showList__ shows ls s

需要注意的是,类型类中的函数可以相互定义。事实上,我们也可以轻松做到:
class Comparable a where
    lessThan :: a -> a -> Bool
    equalsTo :: a -> a -> Bool

    greaterThan :: a -> a -> Bool
    greaterThan lhs rhs = not (lessThan lhs rhs && equalsTo lhs rhs)

然而,关键是:对于任意用户定义的类型类,当您尝试将类型类与诸如 Color 的数据类型关联时,GHC 不知道应该如何实现它们的功能。或 BaseballPlayer .对于 一些类型类,例如 Show , Eq , Ord等,在功能足够简单的情况下,GHC 可以生成默认实现,您当然可以自己覆盖这些实现。

事实上,让我们尝试编译以下内容来进行实验:
data Color = Red | Green | Blue deriving (Comparable)

我得到的结果是这样的:
test.hs:9:43:
    Can't make a derived instance of ‘Comparable Color’:
      ‘Comparable’ is not a derivable class
      Try enabling DeriveAnyClass
    In the data declaration for ‘Color’

当然,可以使用一些 GHC 扩展来扩展 deriving 的功能。 ,但那是另一天:)

关于haskell - 在 Haskell 中推导是什么/意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44744884/

相关文章:

haskell - 为什么 Haskell 不允许这种声明?

scala - 使用具有多个类型参数的类型类

haskell - 派生出具有更多类型变量的新类型

algorithm - 如何为字符串列表编写 Haskell BFS 算法

scala - 有哪些类型级编程的例子?

parsing - 如何从Haskell中的字符串解析UTCTime类型的时间值?

haskell - 为什么 Data.Map 中的键被限制为 Ord 类?

f# - 从两个数组创建元组的更实用的方法

javascript - 在没有 `this` 的情况下访问对象方法

serialization - Data.Binary(或 friend ?)是否有模板 Haskell/派生机制