gpt4 book ai didi

haskell - 为什么这个 eta 扩展是必要的?

转载 作者:行者123 更新时间:2023-12-03 11:57:41 24 4
gpt4 key购买 nike

有人可以帮助我理解这一点/指向我一些阅读 Material 吗?以下工作正常:

type F a b = Functor f => f a -> f b
fComp :: F b c -> F a b -> F a c
fComp f f' = f . f'

但是如果我写 fComp = (.)相反,类型检查器提示:
Couldn't match type ‘b0 -> f c’
with ‘forall (f1 :: * -> *). Functor f1 => f1 b -> f1 c’

(这个具体的例子并不是特别有用;我只是想缩小一个在研究镜头时出现的例子。)

最佳答案

fComp具有更高等级的类型,并且对更高等级类型的类型推断非常有限。如果我们扩展类型同义词,可能会更容易理解(但要长得多!):

fComp :: forall f a b c. Functor f => 
(forall f1. Functor f1 => f1 b -> f1 c) ->
(forall f2. Functor f2 => f2 a -> f2 b) ->
(f a -> f c)
f 的高级类型和 f'在此类型签名中明确指定。这让类型推断开始已经知道 f 的类型。和 f'因此能够将它们与 . 的类型统一起来.

但是,如果您摆脱 ff' , . 的类型有采取不知道。不幸的是,系统不能像这样推断更高等级的类型,所以你会得到一个类型错误。

本质上,编译器无法在类型推断期间创建更高级别的类型来填充未知数,并且必须依赖程序员注释,我们需要名称( ff')和类型签名来获取这些注释。

一个更容易理解的例子是更高等级的 id。功能:
myId :: (forall a. a) -> (forall b. b)

定义 myId x = id x编译,但 myId = id给出以下错误:
/home/tikhon/Documents/so/eta-expansion-needed.hs:11:8:
Couldn't match type ‘b’ with ‘forall a. a’
‘b’ is a rigid type variable bound by
the type signature for myId :: (forall a. a) -> b
at /home/tikhon/Documents/so/eta-expansion-needed.hs:11:1
Expected type: (forall a. a) -> b
Actual type: b -> b
In the expression: id
In an equation for ‘myId’: myId = id
Failed, modules loaded: none.

(请记住 forall b. (forall a. a) -> b(forall a. a) -> (forall b. b) 相同。)

关于haskell - 为什么这个 eta 扩展是必要的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28729288/

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