gpt4 book ai didi

haskell - 使用 MultiParamTypeClasses 时,是否需要在每个类函数中使用每种类型

转载 作者:行者123 更新时间:2023-12-04 18:08:34 25 4
gpt4 key购买 nike

当我使用 MultiParamTypeClasses 时,我可以创建忽略类型参数之一的类函数(即,如下面的“身份”)。

{-# LANGUAGE MultiParamTypeClasses #-}

data Add = Add
data Mul = Mul

class Test a b where
identity::a

instance Test Int Add where
identity = 0

instance Test Int Mul where
identity = 1

(这是一个精简版,当然在完整程序中会有其他函数会使用“b”)。

该示例编译,但我永远无法访问身份!
main = do
putStrLn (show (identity::Int))

导致“没有因使用'身份'而产生的(Test Int b0)实例。

有没有办法访问身份?如果没有,编译器不应该禁止我创建一个不使用所有类型参数的类函数吗?

最佳答案

If not, shouldn't the compiler forbid me from ever creating a class function that doesn't use all type parameters?



也许。实际上,您永远无法使用这样的类方法。但是由于错误总是在编译时发生,所以它并不是很危险。

在某些类似情况下工作的修复程序(但不适用于您的情况):
  • 使未确定类型变量在功能上依赖于其他变量之一。
    {-# LANGUAGE FunctionalDependencies #-}
    class Group_FD g p | g->p where
    identity :: g

    这可能可以像
    data Nat = One | Succ Nat

    instance Group_FD Nat Mult where
    identity = One

    instance Group_FD Int Add where
    identity = 0

    但显然不可能用相同的 g 制作多个实例。元素这样。
  • 为仅依赖于该参数的方法定义一个只有一个参数的单独类。然后使这个类成为另一个类的约束(“父类(super class)”),以“导入”方法:
    class Identity i where
    identity :: i
    class (Identity i) => Test i y

    但是,这对您的应用程序根本没有用,因为您想要 identity 的行为依赖于 Phantom 类型变量。

  • 为了实现你的目标,你必须以某种方式传递你想要的实例的信息。实现这一目标的一种方法是幻像论证:
    class Group_PA g p where
    identity :: p -> g

    instance Group_PA Int Add where
    identity _ = 0

    instance Group_PA Int Mult where
    identity _ = 1

    然后你可以像这样使用

    GHCi> identity Add :: Int
    0
    GHCi> identity Mult :: Int
    1



    也许更惯用的实际上是使标志类型为空
    {-# LANGUAGE EmptyDataDecls #-}
    data Add
    data Mult

    GHCi> identity (undefined :: Add) :: Int
    0
    GHCi> identity (undefined :: Mult) :: Int
    1



    这更清楚地表明 phantom 参数实际上不携带运行时信息,只是控制编译器选择的实例。

    不可否认,这很丑陋。

    ™ 解决方案是制作新型包装器以包含幻影信息。事实上,这样的包装器已经在标准库中了: Sum Product .

    关于haskell - 使用 MultiParamTypeClasses 时,是否需要在每个类函数中使用每种类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20104747/

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