gpt4 book ai didi

haskell - Haskell 中命名字段的令人惊讶的类型推断

转载 作者:行者123 更新时间:2023-12-02 13:32:36 26 4
gpt4 key购买 nike

考虑以下 GHCi 版本 8.2.2 的记录:

GHCi, version 8.2.2: http://www.haskell.org/ghc/  :? for help
Prelude> :set -XRankNTypes
Prelude> data Functor f = Functor { fmap :: forall a b. (a -> b) -> f a -> f b }
Prelude> :t fmap
fmap :: Functor f1 -> (a -> b) -> f2 a -> f2 b
Prelude> :t Functor map
Functor map :: Functor []
Prelude> :t fmap (Functor map)
fmap (Functor map) :: (a -> b) -> [a] -> [b]

如您所见,fmap 的类型被推断为 Functor f1 -> (a -> b) -> f2 a -> f2 b。这是令人惊讶的,因为 f1f2 应该是相同的类型变量,但没有 f1 ~ f2 约束。尽管如此,如果将 fmap 应用于类型为 Functor []Functor map,结果仍然具有类型 (a -> b) -> [a] -> [b] 正如预期的那样。这里发生了什么?我希望 fmap 具有类型 Functor f -> (a -> b) -> f a -> f b

最佳答案

我可以确认此问题影响 GHC 8.2.2,但不影响 8.0.2。更新:看起来它已在 8.4 分支上修复。

这似乎是 GHCi 类型签名显示错误,而不是真正的类型检查器问题,因为如果您使用该程序:

{-# LANGUAGE RankNTypes #-}
module Inference where
data Functor f = Functor { fmap :: forall a b. (a -> b) -> f a -> f b }

并使用ghc -ddump-tc编译它,您可以看到GHC推断出正确的类型:

TYPE SIGNATURES
...
Inference.fmap ::
forall (f :: * -> *).
Inference.Functor f -> forall a b. (a -> b) -> f a -> f b

它似乎也不会影响 GHC 错误消息。如果添加以下行:

main = print Inference.fmap

要生成包含类型的错误消息(“No instance for (Show xxx)”),您还会看到正确的类型。

关于haskell - Haskell 中命名字段的令人惊讶的类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48471810/

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