你能帮我验证下面的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)
你证明的推理似乎是正确的.
我们可以就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:
Run Code Online (Sandbox Code Playgroud)instance Functor ((->) a) where fmap = (.)
所以我们现在有类型:
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)
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |