让我们以fmap . const
作为一个简单的例子,我试着理解它的作用:
fmap :: Functor f => (a -> b) -> f a -> f b
const :: a -> b -> a
我注意到的第一件事是,当我尝试理解a
时b
,fmap . const
含糊不清。使用两个或多个相关签名就是我所说的“GHCI
会话”。
以下是帮助我更好地理解事物的例子:
fmap :: Functor f => (a -> b) -> f a -> f b
const :: c -> d -> c
fmap . const :: Functor g => h -> g i -> g h
让我们绑定g = f
并减少g
:
fmap . const :: Functor f => h -> f i -> f h
选择h :: h
作为有点版本的最不容易混淆的变量名称:
\h -> fmap (const h) :: Functor f => h -> f i -> f h
让我们绑定h = c
并减少h
:
\c -> fmap (const c) :: Functor f => c -> f i -> f c
现在,更容易看到c
中的f c
来自const
的第一个参数。我还看到i
和a
是免费的,因为我不需要“操作”它们。
问题:
GHCI
会话中重复使用字母?GHCI
会话中绑定和减少类型变量?答案 0 :(得分:0)
签名中的类型变量实际上是由隐式通用量词绑定的。有一个语言扩展,使其明确,检查这编译:
{-# LANGUAGE ExplicitForAll #-}
fmapPrime :: forall a b f. Functor f => (a -> b) -> f a -> f b
fmapPrime = fmap
constPrime :: forall a b. a -> b -> a
constPrime = const
fmapConst :: forall a b f. Functor f => b -> f a -> f b
fmapConst = fmap . const
所以你不能说类型变量变量是“重用的”:它们不是免费的。