简体   繁体   English

Haskell中类型的推理

[英]Reasoning about types in Haskell

Chapter 16 of "Haskell Programming from First Principles" on page 995 has an exercise to manually work out how (fmap. fmap) typechecks.第 995 页上的“从第一原理开始的 Haskell 编程”的第 16 章有一个练习来手动(fmap. fmap) It suggests substituting the type of each fmap for the function types in the type of the composition operator:它建议将每个fmap的类型替换为组合运算符类型中的 function 类型:

T1 (.):: (b -> c) -> (a -> b) -> a -> c T1 (.):: (b -> c) -> (a -> b) -> a -> c

T2 fmap:: Functor f => (m -> n) -> fm -> fn T2 fmap:: Functor f => (m -> n) -> fm -> fn

T3 fmap:: Functor g => (x -> y) -> gx -> gy T3 fmap:: Functor g => (x -> y) -> gx -> gy

By (attempting to) substitute T2 and T3 into T1, I arrived at the following:通过(尝试)将 T2 和 T3 代入 T1,我得出以下结论:

T4: ((m -> n) -> fm -> fn) -> ((x -> y) -> gx -> gy) -> a -> c T4: ((m -> n) -> fm -> fn) -> ((x -> y) -> gx -> gy) -> a -> c

Further, it suggests checking the type of (fmap. fmap) to see what the end type should look like.此外,它建议检查(fmap. fmap)的类型以查看最终类型应该是什么样子。

T5: (fmap. fmap):: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b) T5: (fmap. fmap):: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)

I'm having trouble understanding what I should be doing here.我无法理解我应该在这里做什么。 Could any knowledgeable haskellers help get me started, or maybe provide examples of similar exercises that show how to work out types by hand?任何知识渊博的haskellers可以帮助我开始,或者提供类似练习的例子来展示如何手工计算类型?

We proceed step by careful step:我们一步一步小心翼翼地进行:

--- fmap . fmap  =  (.) fmap fmap
--- Functor f, g, ... => ..... 

(.)      :: (   b     ->      c    ) -> (a ->  b ) -> a ->     c
    fmap ::  (d -> e) -> f d -> f e
             --------    ----------
(.) fmap ::                             (a ->d->e) -> a -> f d -> f e
                                             ----          ----------
-- then,

(.) fmap      :: (   a     ->  d  ->  e ) -> a   -> f   d   -> f   e
         fmap ::  (b -> c) -> g b -> g c
                  --------    ---    ---
(.) fmap fmap ::                          (b->c) -> f (g b) -> f (g c)
                                          ------      -----      -----

It is important to consistently rename all the type variables on each separate use of a type, to avoid conflation.重要的是在每次单独使用类型时一致地重命名所有类型变量,以避免混淆。

We use the fact that the arrows associate on the right,我们使用箭头在右侧关联的事实,

 A -> B -> C   ~   A -> (B -> C)

and the type inference rule is并且类型推断规则是

   f   :: A -> B
     x :: C
   --------------
   f x ::      B    ,  A ~ C

(f:: A -> B) (x:: C):: B under the equivalence / unification of types A ~ C and all that it entails. (f:: A -> B) (x:: C):: B在类型A ~ C及其所有内容的等价/统一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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