`<$`函数如何在Functor类中工作?

M.K*_*.K. 1 haskell types type-inference pointfree function-composition

在Functor类定义中,我们将<$函数定义为:

class  Functor f  where
    fmap        :: (a -> b) -> f a -> f b

    (<$)        :: a -> f b -> f a
    (<$)        =  fmap . const
Run Code Online (Sandbox Code Playgroud)

const函数具有以下定义:

const                   :: a -> b -> a
const x _               =  x
Run Code Online (Sandbox Code Playgroud)

我知道这个<$功能相当于:

\x -> fmap (const x)
Run Code Online (Sandbox Code Playgroud)

如何fmap . const等同于上面的lambda表达式?我的函数组合的理解是该输出类型const应该匹配的输入类型fmap,但输入型fmap是功能(a -> b)a这是什么const功能输出.

Eri*_*ikR 5

注意:

(f . g) x = f (g x)
Run Code Online (Sandbox Code Playgroud)

(见定义(.))所以,

(fmap . const) x = fmap (const x)
Run Code Online (Sandbox Code Playgroud)

原始答案

具体来说,让我们使用IO仿函数.

fmap f通过应用计算f结果来进行IO 计算.

例如 - getContents是一个IO String,并且length是一个关于字符串的函数,所以我们可以在getContents上设置fmap长度:

getContents              :: IO String
length                   ::    String -> Int
fmap length getContents  ::              IO Int
Run Code Online (Sandbox Code Playgroud)

运行时,这将读取所有标准输入,获取输入的长度,并返回它(作为IO动作).

现在,const z是一个忽略其参数并始终返回的函数z.所以,如果我要fmap (const 'w')上,getContents我会:

getContents                   :: IO String
const 'w'                     ::    String -> Char
fmap (const 'w') getContents  ::              IO Char
Run Code Online (Sandbox Code Playgroud)

执行时,这将首先读入所有标准输入,然后丢弃该输入并返回字符'w'.