gpt4 book ai didi

haskell - 对于明显相等的实例定义,类型检查失败

转载 作者:行者123 更新时间:2023-12-02 16:40:56 25 4
gpt4 key购买 nike

给出以下类型定义

newtype Constant a b = Constant { getConstant :: a }
deriving (Eq, Show)

仿函数 实例定义有效

instance Functor (Constant a) where
fmap _ (Constant x) = Constant x

而明显等效的实例定义

instance Functor (Constant a) where
fmap _ x = x

因类型检查错误而失败(摘录)

Expected type: Constant a b
Actual type: Constant a a1

使用 GHC 版本 8.0.2。

问题是,为什么这两个(显然等效的)实例定义在类型检查方面表现不同。

最佳答案

如果我们给构造函数起一个不同的名称,以便区分类型级别和值级别,可能会更清楚:

newtype Constant a b = ConstVal { getConstVal :: a }
deriving (Eq, Show)

instance Functor (Constant a) where
fmap _ (ConstVal x) = ConstVal x

现在,为什么你不能写fmap _ x = x

ConstVal 是一个多态构造函数:

ConstVal :: a -> Constant a b

...即

ConstVal :: ∀ a b . a -> Constant a b

尽管全称量词在 Haskell 中是可选的,但它实际上很重要。 ConstVal 基本上有两个附加的类型级参数。换句话说,这不仅仅是一个构造函数,而是一整套构造函数,例如

ConstValBoolBool :: Bool -> Constant Bool Bool
ConstValBoolInt :: Bool -> Constant Bool Int
ConstValBoolChar :: Bool -> Constant Bool Char
...
ConstValCharBool :: Char -> Constant Char Bool
ConstValCharInt :: Char -> Constant Char Int
ConstValCharChar :: Char -> Constant Char Char
...
...

所有这些实际上共享相同的值级别名称ConstVal,但对于类型系统来说它们都是不同的。例如,明确地写出

fmapBoolStringInt :: (String -> Int) -> Constant Bool String -> Constant Bool Int
fmapBoolStringInt _ (ConstValBoolString x) = ConstValBoolInt x

这里很明显,两边的值实际上并不相同,因此不能简化为fmapBoolStringInt _ x = x

关于haskell - 对于明显相等的实例定义,类型检查失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49587756/

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