简体   繁体   中英

Bind type variables in a GHCI session

Let's take fmap . const fmap . const as a simple example where I try to understand what it does:

fmap :: Functor f => (a -> b) -> f a -> f b
const :: a -> b -> a

The fist thing I notice is that a , b are ambiguous when I try to understand fmap . const fmap . const . The use of two or more related signatures together is what I mean by " GHCI session".

Here's example of what would help me understand things better:

fmap :: Functor f => (a -> b) -> f a -> f b
const :: c -> d -> c
fmap . const :: Functor g => h -> g i -> g h

Let's bind g = f and reduce g :

fmap . const :: Functor f => h -> f i -> f h

Pick h :: h as a least-confusing variable name for the pointful version:

\h -> fmap (const h) :: Functor f => h -> f i -> f h

Let's bind h = c and reduce h :

\c -> fmap (const c) :: Functor f => c -> f i -> f c

Now, it is much easier to see that c in fc came from first argument to const . I also see that i and a are free since I did not need to "operate" on them.

Questions:

  • Is there a way to prevent letters being re-used in a GHCI session?
  • Is there a way to bind and reduce type variables in a GHCI session?
  • Finally, I suspect there is an easier way to do the equivalent thought process.

The type variables in signatures are actually bound by an implicit universal quantifier. There is a language extension to make it explicit, check that this compiles :

{-# 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

So you cannot say that the type variables variables are "reused" : they are not free.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM