gpt4 book ai didi

haskell - 参数化类型作为类型参数

转载 作者:行者123 更新时间:2023-12-02 22:29:54 25 4
gpt4 key购买 nike

编译时:

data Rec t = Rec { intPt :: t Int, doublePt :: t Double } deriving Show

type Pt2 a = (a,a)
type Pt3 a = (a,a,a)

type Rec2 = Rec Pt2
type Rec3 = Rec Pt3

main = do
print $ Rec (1,2) (3.4,5.6)
print $ Rec (1,2,3) (5.6, 7.8, 9.0)

我得到了

Unexpected type `t a' where type variable expected
In the declaration of `Rec (t a)'

如何编译并运行?

最佳答案

我无法重现您所报告的确切错误消息,但我可以看到您的示例存在两个问题。

  1. 您正在尝试为 Rec 派生 Show,它通过类型构造函数进行参数化。这对 GHC 来说太难了,目前无法完全自动完成,但您可以通过启用一些扩展使其在实践中发挥作用。

  2. 您正在使用部分应用的类型同义词 Pt2Pt3 作为 Rec 的参数,这是不允许的。您可以通过切换到数据类型来解决这个问题。

更详细一点:要解决问题 1,您可以说:

{-# LANGUAGE StandaloneDeriving, FlexibleContexts, UndecidableInstances #-}

data Rec t = Rec { intPt :: t Int, doublePt :: t Double }
deriving instance (Show (t Int), Show (t Double)) => Show (Rec t)

通过使用独立的派生子句,您可以在 Show 实例上明确指定前提条件。在这种情况下,这些先决条件要求同时启用 FlexibleContextsUndecidableInstances 扩展。

要解决问题 2,您可以执行以下操作:

data Pt2 a = Pt2 a a deriving Show
data Pt3 a = Pt3 a a a deriving Show

type Rec2 = Rec Pt2
type Rec3 = Rec Pt3

可以部分应用数据类型,但不能应用类型同义词。因此,仅当 Pt2 是数据类型时才允许使用 Pt2 作为 Rec 的参数。通过这些修改,您的主要功能类型检查(和工作):

main = do
print $ Rec (Pt2 1 2) (Pt2 3.4 5.6)
print $ Rec (Pt3 1 2 3) (Pt3 5.6 7.8 9.0)

关于haskell - 参数化类型作为类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12460837/

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