表达式fmap的评估(*3)(+ 5)1

Šef*_*ana 6 haskell

你能帮我验证下面的Haskell表达式的评估:fmap(*3)(+ 5)1?我特别努力正确解析fmap xy z.

谢谢

我的试用版:

fmap (*3) (+5) 1 -- nothing to do 1 is 1
=> (fmap (*3)) (+5) 1 -- function application infixl 10
=> ((fmap (*3)) (+5)) 1 -- function application infixl 10
=> ((fmap (*3) (+5)) 1 -- (f (x) y) equivalent to (f x y)
=> ((*3) . (+5)) 1 -- fmap f g = f.g; 
=> (*3) ((+5) 1) -- (f.g) x = f (g x) 
=> (*3) 6 
=> 18
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 7

你证明的推理似乎是正确的.

我们可以就Haskell如何做到这一点做出更严格的回答.首先,将激活类型检查器.

哈斯克尔看到了这个表达

((fmap (*3)) (+5)) 1
Run Code Online (Sandbox Code Playgroud)

所以首先它做了一些类型的推理:

fmap :: Functor f => (a -> b) -> f a -> f b
(*3) :: Num c => c -> c
(+5) :: Num d => d -> d
1 :: Num e => e
Run Code Online (Sandbox Code Playgroud)

因为我们所说的fmap(*3)这因此意味着a -> b ~ c -> c,这样a ~ b ~ c,所以我们得到:

fmap :: (Num a, Functor f) => (a -> a) -> f a -> f a
(*3) :: Num a => a -> a
(+5) :: Num d => d -> d
1 :: Num e => e
Run Code Online (Sandbox Code Playgroud)

所以这意味着fmap (*3)有类型fmap (*3) :: (Num a, Functor f) => f a -> f a.既然(+5) :: Num d => d -> d是该函数的参数,我们就看到了f a ~ d -> d.或者以更规范的形式:f a ~ (->) d d.所以这意味着f ~ (-> d)a ~ d.这适用,因为没有 Functor(->) a:

instance Functor ((->) a) where
    fmap = (.)
Run Code Online (Sandbox Code Playgroud)

所以我们现在有类型:

fmap :: Num a => (a -> a) -> (a -> a) -> (a -> a)
fmap :: Num a => (a -> a) -> (a -> a) -> a -> a
fmap = (.)
(*3) :: Num a => a -> a
(+5) :: Num a => a -> a
1 :: Num e -> e
Run Code Online (Sandbox Code Playgroud)

所以这意味着fmap (*3) (+5)有类型(->) a a.我们用这个函数来调用1,这意味着e ~ a,所以:

fmap :: Num a => (a -> a) -> (a -> a) -> a -> a
fmap = (.)
(*3) :: Num a => a -> a
(+5) :: Num a => a -> a
1 :: Num a -> a
Run Code Online (Sandbox Code Playgroud)

所以现在我们输入检查函数,我们得出结论fmap = (.),所以我们基本上写了:

(((.) (*3)) (+5)) 1
Run Code Online (Sandbox Code Playgroud)

现在如果我们想要评估这个,我们得到:

   (((.) (*3)) (+5)) 1
-> (*3) ((+5) 1)
-> (*3) 6
-> 18
Run Code Online (Sandbox Code Playgroud)